我正在尝试写入具有大记录的excel的数据表。我正在尝试使用分而治之的stratergy,其中每个线程被分配以写入相应的excelworkbook表。但是我获取文件是只读,单击确定覆盖文件。
class Program
{
int processorCount = 2;
static volatile bool processing = true;
DataTable employeeTable = new DataTable("Employee");
ManualResetEvent mre = new ManualResetEvent(false);
AutoResetEvent ar = new AutoResetEvent(true);
int record_count;
static void Main(string[] args)
{
Program p = new Program();
//Create an Emplyee DataTable
p.employeeTable.Columns.Add("Employee ID");
p.employeeTable.Columns.Add("Employee Name");
for (int i = 0; i <= 2; i++)
{
p.employeeTable.Rows.Add(i.ToString(), "ABC");
}
p.record_count = p.employeeTable.Rows.Count / p.processorCount;
Excel.Application excelApp = new Excel.Application();
//Create an Excel workbook instance and open it from the predefined location
Excel.Workbook excelWorkBook1 = excelApp.Workbooks.Open(@"F:\Org.xlsx");
Thread[] threads = new Thread[3];
for (int i = 0; i < 3; i++)
{
// p.ExportDataSetToExcel(i);
ParameterizedThreadStart ps = new ParameterizedThreadStart(p.ExportDataSetToExcel);
threads[i] = new Thread(ps);
threads[i].Start(new Custom() { sheetNo = i, excelWorkBook = excelWorkBook1 });
}
for (int j = 0; j < 3; j++)
{
threads[j].Join();
}
Console.WriteLine("Succeess");
Console.ReadKey();
}
private void ExportDataSetToExcel(object sheet1)
{
lock (this)
{
bool found = false;
Excel.Worksheet excelWorkSheet;
int sheetNo = ((Custom)sheet1).sheetNo;
Excel.Workbook excelWorkBook = ((Custom)sheet1).excelWorkBook;
excelWorkSheet = (excelWorkBook).Sheets["Sheet" + ((int)sheetNo + 1).ToString()];
for (int i = 1; i < employeeTable.Columns.Count + 1; i++)
{
excelWorkSheet.Cells[1, i] = employeeTable.Columns[i - 1].ColumnName;
}
int baseIndex = (int)sheetNo * record_count;
for (int j = baseIndex; j < baseIndex + record_count; j++)
{
for (int k = 0; k < employeeTable.Columns.Count; k++)
{
excelWorkSheet.Cells[j + 2, k + 1] = employeeTable.Rows[j].ItemArray[k].ToString();
}
}
Console.WriteLine(sheetNo.ToString());
Console.WriteLine("\n");
(excelWorkBook).Save();
(excelWorkBook).Close();
}
}
}**strong text**
public class Custom
{
public int sheetNo;
public Excel.Workbook excelWorkBook;
}
答案 0 :(得分:2)
不是通过OLE或VSTO使用互操作,而是使用EPPlus,NPOI之类的库或直接使用Open XML SDK来创建Excel文件。
Interop强制您在单个线程上工作,并且您始终支付CPU互操作成本,浪费的CPU和内存以运行Excel,最后支付CPU和IO以保存文件。
另一方面,Open XML SDK和其他库甚至不需要Excel。所有操作都在内存中,您只需支付CPU和IO成本来保存文件。结果,它们的速度提高了几个数量
因此,您可以在Web和服务器应用程序中使用它们,因为使用Interop和VSTO是不可能的
EPPlus有一些很好的功能,比如从DataTable(LoadFromDataTable)或LINQ查询(LoadFromCollection)创建Excel表,这使得导出数据非常容易,例如:
using (var excelFile = new ExcelPackage(targetFile))
{
var worksheet = excelFile.Workbook.Worksheets.Add("Sheet1");
var tableRange=worksheet.Cells["A1"].LoadFromCollection(employees, true);
excelFile.Save();
}
<强>更新强>
我刚刚在评论中读到OP想要导出大量行并认为Excel有一些限制。但事实并非如此,但情况与开始时完全不同。
自2010年以来,Excel对行数没有任何限制。只要机器有足够的内存,它就可以通过PowerPivot / PowerQuery处理多个数百万行的源。在2010年,文件大小有2GB的人为限制(以适应SharePoint),但我认为这在2013年被删除。这是一个巨大的大小,因为PowerPivot使用与Analysis Services相同的列压缩。
在这种情况下,最好的选择是创建一个带有PowerPivot连接的Excel文件,将其提供给用户并让他们随时刷新数据。
不幸的是,这是Excel的一项功能,而不是文件格式。这意味着您无法使用SDK创建包含列压缩数据的文件,但必须再次使用interop / VSTO。但在这种情况下,它的Excel会拉动和压缩数据。
答案 1 :(得分:1)
不幸的是,Excel不是多线程的。但我建议你写的写作更有效。逐个单元写入是减速的最大部分。
消除这两个因素(组织数据并将其写入)会将实际写入时间减少到可能消除同时写入它的需要。
我有一个旧的VSTO项目,我必须从数据库中编写数据集,然后将数据提取为二维数组,然后将整个数组写入工作表中的某个区域,如下所示:
Microsoft.Office.Tools.Excel.Worksheet TheSheet;
private void PublishToSheet( int totalRows, int maxColumns, ref string[,] OutputArray )
{
Excel.Range Range = TheSheet.Range["A1", TheSheet.Cells[totalRows, maxColumns]];
Range.NumberFormat = "@";
Range.Value2 = OutputArray;
LastRow = totalRows;
LastColumn = maxColumns;
}