C# 使用 Interop 写入打开的 Excel 文件
C# Write to an open Excel file using Interop
我在这方面遇到了可笑的困难,但我需要能够使用 Interop 连接到打开的 excel 文件,然后写入该文件。
文件由外部进程打开,然后此应用程序稍后进入以写入工作簿。我可以让它打开一个文件并写入活动工作簿。但我找不到连接到以前的工作簿并写入的方法。
我一直在使用 Marshal.GetActiveObject
,但我很快就会 运行 计算机上的应用程序打开了多个文件,需要写入一个很可能不是活动文件的文件。
更新:
System.Runtime.InteropServices.Marshal.BindToMoniker
可用于访问在 Excel 中打开的文件,或者如果尚未打开则打开它:
var wb = Marshal.BindToMoniker(@"C:\x.xlsx") as Microsoft.Office.Interop.Excel.Workbook;
旧答案:
GetObject
可以参考Microsoft.VisualBasic
使用(如果需要也会打开文件):
object o = Microsoft.VisualBasic.Interaction.GetObject(@"C:\x.xlsx", "Excel.Application");
var wb = o as Microsoft.Office.Interop.Excel.Workbook;
if (wb != null)
{
Microsoft.Office.Interop.Excel.Application xlApp = wb.Application;
// your code
}
参考 Microsoft.VisualBasic
可能可以通过检查 GetObject
源代码来避免 https://github.com/Microsoft/referencesource/blob/master/Microsoft.VisualBasic/runtime/msvbalib/Interaction.vb#L1039
这似乎是 C# 版本
using Excel = Microsoft.Office.Interop.Excel;
Excel.Application excel = null;
try
{
excel = (Excel.Application)Marshal.GetActiveObject("Excel.Application");
}
catch (COMException exc)
{
// ....
}
显然假设文件是由 excel 应用程序在 same 机器上打开的。
但是 重点是 Marshal.GetActiveObject
将始终 return 它在 ROT 上找到的 第一个 实例( running object table). This is because Office doesn't register new objects. You have to get the application from the child windows, like suggested in this more complicated answer.
这样试试。
Microsoft.Office.Interop.Excel.Application oXL;
Microsoft.Office.Interop.Excel._Workbook oWB;
Microsoft.Office.Interop.Excel._Worksheet oSheet;
Microsoft.Office.Interop.Excel.Range oRng;
object misvalue = System.Reflection.Missing.Value;
try
{
//Start Excel and get Application object.
oXL = new Microsoft.Office.Interop.Excel.Application();
oXL.Visible = true;
//Get a new workbook.
oWB = (Microsoft.Office.Interop.Excel._Workbook)(oXL.Workbooks.Add(""));
oSheet = (Microsoft.Office.Interop.Excel._Worksheet)oWB.ActiveSheet;
//Add table headers going cell by cell.
oSheet.Cells[1, 1] = "First Name";
oSheet.Cells[1, 2] = "Last Name";
oSheet.Cells[1, 3] = "Full Name";
oSheet.Cells[1, 4] = "Salary";
//Format A1:D1 as bold, vertical alignment = center.
oSheet.get_Range("A1", "D1").Font.Bold = true;
oSheet.get_Range("A1", "D1").VerticalAlignment =
Microsoft.Office.Interop.Excel.XlVAlign.xlVAlignCenter;
// Create an array to multiple values at once.
string[,] saNames = new string[5, 2];
saNames[0, 0] = "John";
saNames[0, 1] = "Smith";
saNames[1, 0] = "Tom";
saNames[4, 1] = "Johnson";
//Fill A2:B6 with an array of values (First and Last Names).
oSheet.get_Range("A2", "B6").Value2 = saNames;
//Fill C2:C6 with a relative formula (=A2 & " " & B2).
oRng = oSheet.get_Range("C2", "C6");
oRng.Formula = "=A2 & \" \" & B2";
//Fill D2:D6 with a formula(=RAND()*100000) and apply format.
oRng = oSheet.get_Range("D2", "D6");
oRng.Formula = "=RAND()*100000";
oRng.NumberFormat = "[=10=].00";
//AutoFit columns A:D.
oRng = oSheet.get_Range("A1", "D1");
oRng.EntireColumn.AutoFit();
oXL.Visible = false;
oXL.UserControl = false;
oWB.SaveAs("c:\test\test505.xls", Microsoft.Office.Interop.Excel.XlFileFormat.xlWorkbookDefault, Type.Missing, Type.Missing,
false, false, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
oWB.Close();
从这里开始:
How to write some data to excel file(.xlsx)
另外,看看这个。
using System;
using System.Drawing;
using System.Windows.Forms;
using Excel = Microsoft.Office.Interop.Excel;
namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
try
{
System.Data.OleDb.OleDbConnection MyConnection ;
System.Data.OleDb.OleDbCommand myCommand = new System.Data.OleDb.OleDbCommand();
string sql = null;
MyConnection = new System.Data.OleDb.OleDbConnection("provider=Microsoft.Jet.OLEDB.4.0;Data Source='c:\csharp.net-informations.xls';Extended Properties=Excel 8.0;");
MyConnection.Open();
myCommand.Connection = MyConnection;
sql = "Insert into [Sheet1$] (id,name) values('5','e')";
myCommand.CommandText = sql;
myCommand.ExecuteNonQuery();
MyConnection.Close();
}
catch (Exception ex)
{
MessageBox.Show (ex.ToString());
}
}
}
}
我在这方面遇到了可笑的困难,但我需要能够使用 Interop 连接到打开的 excel 文件,然后写入该文件。
文件由外部进程打开,然后此应用程序稍后进入以写入工作簿。我可以让它打开一个文件并写入活动工作簿。但我找不到连接到以前的工作簿并写入的方法。
我一直在使用 Marshal.GetActiveObject
,但我很快就会 运行 计算机上的应用程序打开了多个文件,需要写入一个很可能不是活动文件的文件。
更新:
System.Runtime.InteropServices.Marshal.BindToMoniker
可用于访问在 Excel 中打开的文件,或者如果尚未打开则打开它:
var wb = Marshal.BindToMoniker(@"C:\x.xlsx") as Microsoft.Office.Interop.Excel.Workbook;
旧答案:
GetObject
可以参考Microsoft.VisualBasic
使用(如果需要也会打开文件):
object o = Microsoft.VisualBasic.Interaction.GetObject(@"C:\x.xlsx", "Excel.Application");
var wb = o as Microsoft.Office.Interop.Excel.Workbook;
if (wb != null)
{
Microsoft.Office.Interop.Excel.Application xlApp = wb.Application;
// your code
}
参考 Microsoft.VisualBasic
可能可以通过检查 GetObject
源代码来避免 https://github.com/Microsoft/referencesource/blob/master/Microsoft.VisualBasic/runtime/msvbalib/Interaction.vb#L1039
这似乎是 C# 版本
using Excel = Microsoft.Office.Interop.Excel;
Excel.Application excel = null;
try
{
excel = (Excel.Application)Marshal.GetActiveObject("Excel.Application");
}
catch (COMException exc)
{
// ....
}
显然假设文件是由 excel 应用程序在 same 机器上打开的。
但是 重点是 Marshal.GetActiveObject
将始终 return 它在 ROT 上找到的 第一个 实例( running object table). This is because Office doesn't register new objects. You have to get the application from the child windows, like suggested in this more complicated answer.
这样试试。
Microsoft.Office.Interop.Excel.Application oXL;
Microsoft.Office.Interop.Excel._Workbook oWB;
Microsoft.Office.Interop.Excel._Worksheet oSheet;
Microsoft.Office.Interop.Excel.Range oRng;
object misvalue = System.Reflection.Missing.Value;
try
{
//Start Excel and get Application object.
oXL = new Microsoft.Office.Interop.Excel.Application();
oXL.Visible = true;
//Get a new workbook.
oWB = (Microsoft.Office.Interop.Excel._Workbook)(oXL.Workbooks.Add(""));
oSheet = (Microsoft.Office.Interop.Excel._Worksheet)oWB.ActiveSheet;
//Add table headers going cell by cell.
oSheet.Cells[1, 1] = "First Name";
oSheet.Cells[1, 2] = "Last Name";
oSheet.Cells[1, 3] = "Full Name";
oSheet.Cells[1, 4] = "Salary";
//Format A1:D1 as bold, vertical alignment = center.
oSheet.get_Range("A1", "D1").Font.Bold = true;
oSheet.get_Range("A1", "D1").VerticalAlignment =
Microsoft.Office.Interop.Excel.XlVAlign.xlVAlignCenter;
// Create an array to multiple values at once.
string[,] saNames = new string[5, 2];
saNames[0, 0] = "John";
saNames[0, 1] = "Smith";
saNames[1, 0] = "Tom";
saNames[4, 1] = "Johnson";
//Fill A2:B6 with an array of values (First and Last Names).
oSheet.get_Range("A2", "B6").Value2 = saNames;
//Fill C2:C6 with a relative formula (=A2 & " " & B2).
oRng = oSheet.get_Range("C2", "C6");
oRng.Formula = "=A2 & \" \" & B2";
//Fill D2:D6 with a formula(=RAND()*100000) and apply format.
oRng = oSheet.get_Range("D2", "D6");
oRng.Formula = "=RAND()*100000";
oRng.NumberFormat = "[=10=].00";
//AutoFit columns A:D.
oRng = oSheet.get_Range("A1", "D1");
oRng.EntireColumn.AutoFit();
oXL.Visible = false;
oXL.UserControl = false;
oWB.SaveAs("c:\test\test505.xls", Microsoft.Office.Interop.Excel.XlFileFormat.xlWorkbookDefault, Type.Missing, Type.Missing,
false, false, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
oWB.Close();
从这里开始:
How to write some data to excel file(.xlsx)
另外,看看这个。
using System;
using System.Drawing;
using System.Windows.Forms;
using Excel = Microsoft.Office.Interop.Excel;
namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
try
{
System.Data.OleDb.OleDbConnection MyConnection ;
System.Data.OleDb.OleDbCommand myCommand = new System.Data.OleDb.OleDbCommand();
string sql = null;
MyConnection = new System.Data.OleDb.OleDbConnection("provider=Microsoft.Jet.OLEDB.4.0;Data Source='c:\csharp.net-informations.xls';Extended Properties=Excel 8.0;");
MyConnection.Open();
myCommand.Connection = MyConnection;
sql = "Insert into [Sheet1$] (id,name) values('5','e')";
myCommand.CommandText = sql;
myCommand.ExecuteNonQuery();
MyConnection.Close();
}
catch (Exception ex)
{
MessageBox.Show (ex.ToString());
}
}
}
}