距离上次写那篇《
也说C#实现对Word文件读写》已经一年多时间了,一直想小结一些C#读写Excel文件的相关技巧,毕竟Excel打印更为方便和实用,一个是Excel打印输出编码比Word文件打印数据简单些,另一个是Excel本身对数据超强计算处理功能;赶巧最近项目又涉及Excel报表统计打印的问题,所以在把其中的一些技术记录下来与大家一起分析讨论,次篇主要涉及两个方面内容:
1、 读写Excel文件
A、设计Excel模版
B、打开一个目标文件并且读取模版内容
C、目标文件按格式写入需要的数据
D、保存并且输出目标Excel文件
2、 Excel对象资源释放,这个在以前项目没有注意彻底释放使用到Excel对象,对客户计算机资源造成一定浪费,此次得到彻底解决。
下面是一个Excel打印输出的Demo
1、 创建一个叫DemoExcel的项目
2、 引用COM,包括:Microsoft.Excel.x.0.Object.Library,Microsoft.Office.x.0.Object.Library
建议安装正版OFFICE,而且版本在11.0以上(Office2003以上),引用以上两个Com后,在项目引用栏发现多了Excel、Microsoft.Office.Core,VBIDE三个 Library.
3、 下面建立一些模拟的数据,此处为街镇信息
using
System;
using
System.Collections.Generic;
using
System.ComponentModel;
using
System.Data;
using
System.Drawing;
using
System.Text;
using
System.Windows.Forms;
using
Microsoft.Office.Interop.Excel;
using
Microsoft.Office.Core;
using
System.IO;
using
System.Reflection;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
namespace
DemoExcel
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
public partial class Form1 : Form
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
private object missing = Missing.Value;
private Microsoft.Office.Interop.Excel.Application ExcelRS;
private Microsoft.Office.Interop.Excel.Workbook RSbook;
private Microsoft.Office.Interop.Excel.Worksheet RSsheet;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
public Form1()
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
InitializeComponent();
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
private void Form1_Load(object sender, EventArgs e)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
// TODO: 这行代码将数据加载到表“dataSet1.STREET”中。您可以根据需要移动或移除它。
this.sTREETTableAdapter.Fill(this.dataSet1.STREET);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
private void button1_Click(object sender, EventArgs e)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
string OutFilePath = System.Windows.Forms.Application.StartupPath + @" emp.xls";
string TemplateFilePath = System.Windows.Forms.Application.StartupPath + @"模版.xls";
PrintInit(TemplateFilePath,OutFilePath);
}
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
Excle输出前初始化#region Excle输出前初始化
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/**//// <summary>
///
/// </summary>
/// <returns></returns>
public bool PrintInit(string templetFile, string outputFile)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
try
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
if (templetFile == null)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
MessageBox.Show("Excel模板文件路径不能为空!");
return false;
}
if (outputFile == null)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
MessageBox.Show("输出Excel文件路径不能为空!");
return false;
}
//把模版文件templetFile拷贝到目输出文件outputFile中,并且目标文件可以改写
System.IO.File.Copy(templetFile, outputFile, true);
if (this.ExcelRS != null)
ExcelRS = null;
//实例化ExcelRS对象
ExcelRS = new Microsoft.Office.Interop.Excel.ApplicationClass();
//打开目标文件outputFile
RSbook = ExcelRS.Workbooks.Open(outputFile, missing, missing, missing, missing, missing,
missing, missing, missing, missing, missing, missing, missing, missing, missing);
//设置第一个工作溥
RSsheet = (Microsoft.Office.Interop.Excel.Worksheet)RSbook.Sheets.get_Item(1);
//激活当前工作溥
RSsheet.Activate();
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
在当前工作溥写入内容#region 在当前工作溥写入内容
for (int i = 0; i < this.dataGridView1.RowCount; i++)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
RSsheet.Cells[3 + i, 1] = this.dataGridView1[0, i].Value.ToString();
RSsheet.Cells[3 + i, 2] = this.dataGridView1[1, i].Value.ToString();
RSsheet.Cells[3 + i, 3] = this.dataGridView1[2, i].Value.ToString();
}
#endregion
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
//保存目标文件
RSbook.Save();
//设置DisplayAlerts
ExcelRS.DisplayAlerts = false;
ExcelRS.Visible = true;
//ExcelRS.DisplayAlerts = true;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
//释放对象
RSsheet = null;
RSbook = null;
ExcelRS = null;
//释放内存
GcCollect();
}
catch (Exception ex)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
MessageBox.Show(ex.ToString());
return false;
}
return true;
}
#endregion
public void GcCollect()
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
}
}
}
特别说明:
a、引用Microsoft.Office.Interop.Excel;using Microsoft.Office.Core;
b、(关键)在程序中特别释放Excel资源的时候既要设置对象为null,又要强制回收内存,这样才能彻底回收资源。
c、引用的Office组建版本是个敏感问题,不同版本之间有细微差别,需要分别处理。