C++/CLI使用Office.Interop库创建excel,同时解决写入速度慢的问题

bool WriteExcelFile_OfficeInterop(String^ path, DataSet^ dt,
		const std::vector<std::string>& sheetName, bool hideColumnName)
	{
		// If the file already exists, delete it and then generate file
		if (System::IO::File::Exists(path))
		{
			try
			{
				System::IO::File::Delete(path);
			}
			catch (System::Exception^ e)
			{
				System::Windows::Forms::MessageBox::Show("Delete Excel File Failed, Please Check File Statue.",
					"Delete File Error",
					System::Windows::Forms::MessageBoxButtons::OK,
					System::Windows::Forms::MessageBoxIcon::Error);
				return false;
			}
		}

		Excel::Application^ excelApp = nullptr;
		Excel::_Workbook^ workbook = nullptr;
		Excel::Worksheet^ worksheet = nullptr;
		Excel::Range^ range = nullptr;
		Excel::Range^ firstRow = nullptr;
		Excel::Sort^ sort = nullptr;
		bool ret = true;
		try
		{
			//Create a new instance of Excel application
			excelApp = gcnew Excel::ApplicationClass();
			//Create a new workbook
			workbook = excelApp->Workbooks->Add(true);

			for (int i = 0; i < dt->Tables->Count; ++i)
			{
				//Create a new worksheet
				worksheet = (Excel::Worksheet^)workbook->Sheets->Add(Type::Missing, workbook->Sheets[workbook->Worksheets->Count], Type::Missing, Excel::XlSheetType::xlWorksheet);
				//Set the name of the worksheet
				worksheet->Name = StringToSystemString(sheetName[i]);

				// headerRowIndex == 0 means that header is hid
				int headerRowIndex = 0;
				if (hideColumnName == false)
				{
					// the header will occupy 1 row
					headerRowIndex = 1;
					//Fill the header row with column names
					for (int j = 0; j < dt->Tables[i]->Columns->Count; ++j)
					{
						worksheet->Cells[1, j + 1] = dt->Tables[i]->Columns[j]->ColumnName;
					}
				}

				//Fill the data rows using range object
				int numCols = dt->Tables[i]->Columns->Count;
				int numRows = dt->Tables[i]->Rows->Count;
				range = worksheet->Range[worksheet->Cells[headerRowIndex + 1, 1], 
										 worksheet->Cells[headerRowIndex + numRows, numCols]];

				// 使用二维数组加速写入
				array<System::Object^, 2>^ dataArray = gcnew array<System::Object^, 2>(numRows, numCols);
				for (int row = 0; row < numRows; ++row)
				{
					for (int col = 0; col < numCols; ++col)
					{
						dataArray[row, col] = dt->Tables[i]->Rows->default[row]->default[col];
					}
				}
				range->Value2 = dataArray;
				
				// UsedRange : not empty column
				worksheet->UsedRange->Columns->AutoFit();
			}
			// delete default empty sheet which is created when create a workbook
			safe_cast<Excel::Worksheet^>(workbook->Sheets["Sheet1"])->Delete();
			// select the first sheet
			safe_cast<Excel::_Worksheet^>(workbook->Sheets[1])->Activate();
			//Save the workbook
			workbook->SaveAs(path, Type::Missing, Type::Missing,
				Type::Missing, Type::Missing, Type::Missing, Microsoft::Office::Interop::Excel::XlSaveAsAccessMode::xlNoChange,
				Type::Missing, Type::Missing, Type::Missing, Type::Missing, Type::Missing);

			//Close the workbook
			workbook->Close(Type::Missing, Type::Missing, Type::Missing);

			//Quit the Excel application
			excelApp->Quit();
		}
		catch (System::Exception^ e)
		{
			System::Windows::Forms::MessageBox::Show(e->Message,
				"Write File Error",
				System::Windows::Forms::MessageBoxButtons::OK,
				System::Windows::Forms::MessageBoxIcon::Error);

			//Close the workbook and quit the Excel application
			if (workbook != nullptr)
			{
				workbook->Close(Type::Missing, Type::Missing, Type::Missing);
			}
			if (excelApp != nullptr)
			{
				excelApp->Quit();
			}
			ret = false;
		}
		finally
		{
			//Release COM objects
			if (sort != nullptr)
			{
				Marshal::ReleaseComObject(sort);
			}
			if (firstRow != nullptr)
			{
				Marshal::ReleaseComObject(firstRow);
			}
			if (range != nullptr)
			{
				Marshal::ReleaseComObject(range);
			}

			if (worksheet != nullptr)
			{
				Marshal::ReleaseComObject(worksheet);
			}
			if (workbook != nullptr)
			{
				Marshal::ReleaseComObject(workbook);
			}
			if (excelApp != nullptr)
			{
				Marshal::ReleaseComObject(excelApp);
			}
		}
		return ret;
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 可以使用 NPOI 来读取 Excel 文件,它是一个开源的 .NET ,可以在不使用 Microsoft Office 的情况下读取和写入 Excel 文件。 使用 NPOI 读取 Excel 工作簿的基本流程如下: 1. 使用 NPOI 的 `FileStream` 类打开 Excel 文件。 2. 使用 NPOI 的 `HSSFWorkbook` 或 `XSSFWorkbook` 类读取 Excel 文件。 3. 通过工作簿实例可以读取到所有的工作表(Sheet) 4. 使用工作表实例可以读取到工作表中的数据 NPOI需要下载安装 如果要给项目安装依赖可以在包管理器控制台输入 ``` PM> Install-Package NPOI ``` 之后就可以直接使用 代码示例: ```c# using (FileStream file = new FileStream(filePath, FileMode.Open, FileAccess.Read)) { IWorkbook workbook = new HSSFWorkbook(file); ISheet sheet = workbook.GetSheetAt(0); IRow row = sheet.GetRow(0); ICell cell = row.GetCell(0); string value = cell.ToString(); } ``` 这个例子是读取一个Excel的第一个工作表的第一个单元格的内容。 ### 回答2: WinForm是一种用于开发Windows桌面应用程序的GUI框架,通常用于创建用户友好的界面。在使用WinForm读取Excel工作簿时,我们有多种方法可以实现,其中一种是不使用Microsoft.Office.Interop.Excel。 可以使用第三方,例如NPOI,来读取Excel工作簿。NPOI是一个开源的.NET,用于创建和处理Office文档,包括Excel。以下是使用NPOI来读取Excel工作簿的步骤: 1. 首先,我们需要下载并引用NPOI。可以在NPOI的官方网站(https://github.com/nissl-lab/npoi)上找到最新版本的。 2. 创建一个WinForm应用程序并添加一个按钮控件。 3. 在按钮的Click事件处理程序中,编写代码来读取Excel工作簿。 ```csharp private void btnRead_Click(object sender, EventArgs e) { string filePath = "path_to_excel_file"; // Excel文件路径 using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read)) { IWorkbook workbook; workbook = new XSSFWorkbook(fileStream); // 使用XSSFWorkbook读取xlsx文件,如果是xls文件,则使用HSSFWorkbook ISheet sheet = workbook.GetSheetAt(0); // 获取第一个工作表 for (int row = 0; row <= sheet.LastRowNum; row++) { IRow excelRow = sheet.GetRow(row); if (excelRow != null) { for (int column = 0; column < excelRow.LastCellNum; column++) { ICell cell = excelRow.GetCell(column); string cellValue = cell?.ToString(); // 读取单元格的值 // 处理单元格的值 } } } } } ``` 在这个示例中,我们使用NPOI的XSSFWorkbook类来读取xlsx文件。如果要读取xls文件,则需要使用HSSFWorkbook类。使用workbook.GetSheetAt(0)方法获取第一个工作表,然后使用循环遍历每一行和每个单元格,读取单元格的值并进行处理。 使用NPOI可以方便地读取Excel工作簿,而不需要使用Microsoft.Office.Interop.Excel。它是一个功能强大且灵活的工具,适用于WinForm应用程序。 ### 回答3: WinForms是使用C#编写的桌面应用程序开发框架,如果我们不使用Microsoft.Office.Interop.Excel来读取Excel的工作簿,我们可以使用第三方来完成相同的任务。 一个常用的第三方是EPPlus,它是一个开源的.NET,提供了许多用于读写和操作Excel文件的功能。 首先,我们需要在我们的WinForms项目中引入EPPlus。我们可以通过NuGet包管理器来安装EPPlus。 以下是一个示例代码,演示如何使用EPPlus来读取一个Excel工作簿: ```csharp using OfficeOpenXml; // ... private void ReadExcel() { // Excel文件的路径 string filePath = "路径\\文件名.xlsx"; // 创建一个ExcelPackage对象,用于打开Excel文件 using (ExcelPackage package = new ExcelPackage(new FileInfo(filePath))) { // 获取第一个工作表 ExcelWorksheet worksheet = package.Workbook.Worksheets[1]; // 获取工作表的行数和列数 int rowCount = worksheet.Dimension.Rows; int colCount = worksheet.Dimension.Columns; // 遍历工作表的每一行 for (int row = 1; row <= rowCount; row++) { // 遍历每一列 for (int col = 1; col <= colCount; col++) { // 读取单元格的值 string cellValue = worksheet.Cells[row, col].Value?.ToString(); // 将值输出到控制台 Console.WriteLine("单元格({0},{1}): {2}", row, col, cellValue); } } } } ``` 在上面的代码中,我们首先指定要打开的Excel文件路径,然后使用ExcelPackage类创建一个ExcelPackage对象。通过该对象,我们可以打开Excel文件,获取工作表,并遍历每个单元格以读取其值。 需要注意的是,EPPlus还提供了许多其他功能,如写入Excel文件、使用表格样式、添加图表等。我们可以根据需要在代码中使用这些功能来进一步操作Excel文件。 总而言之,通过使用第三方EPPlus,我们可以在不使用Microsoft.Office.Interop.Excel的情况下,实现在WinForms应用程序中读取Excel工作簿的功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ethan Wilson

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值