最近做的项目中,需要实现如下功能:在Winform中,将DataGridView中的数据导出到某个Excel文件,以及读取某个存在的Excel文件的内容,并更新数据库。
为了实现这些功能,选择去用Com组件。
像下面这种表:
点击右上角的 导出Excel 按钮,出现弹窗选择存储路径:
取好文件名点确定,就能在该路径下保存一个xlsx文件,打开文件后效果如下:
可以看到,程序界面DataGridView中的内容完整地导入了xlsx文件,并且单元格合并、字符居中显示都已实现。
Excel表格的导入操作流程和上面相同,点击按钮选取路径下的一个文件。这里就不截图了。
1 SaveFileDialog saveDialog = new SaveFileDialog(); 来创造弹窗,获取选择的文件名。
2 在右边资源管理器中,解决方案——引用——添加引用——程序集(扩展)中找到Microsoft.Office.Interop.Excel——确定
在命名空间中加上:using Excel = Microsoft.Office.Interop.Excel;
3 创建Excel对象,建立虚表
Application 相当于建立一个Excel程序,想象成电脑上打开了Excel程序
Workbooks 是application的一个属性,是当前EXCEL进程打开的所有工作簿数组,使用workbooks[1]、workbooks[2]可以访问他们。
Workbook 是类型,是工作簿,一个EXCEL文件(包含多个工作表)就是一个工作簿
worksheet 是里面包含的表,你在桌面右键新建个excel,默认里面就有3个sheet,sheet1,sheet2,sheet3.就这个意思。
4 根据实际情况对虚表进行写数据。可以参考下面的代码。
5 复制虚表,保存文件,关闭Application,销毁资源。
导入的前两点和导出相同,第3点开始有区别。
1,2 ,5 同导出
3 workbook打开文件,worksheet获取b表格
4 读取Worksheet指定行列的数据。可以参考下面的代码。
Cell [ 行 , 列 ] ,往里面填行列来指定某个单元格。
注:需加(Excel.Range)进行强转,否则无法读到单元格的。
private void ExportExcel(object sender, EventArgs e,DataGridView myGrid)
{
string fileName = "";
string saveFileName = "";
SaveFileDialog saveDialog = new SaveFileDialog();
saveDialog.DefaultExt = "xlsx";
saveDialog.Filter = "Excel文件|*.xlsx";
saveDialog.FileName = fileName;
saveDialog.ShowDialog();
saveFileName = saveDialog.FileName;
if (saveFileName.IndexOf(":") < 0) return; //被点了取消
Microsoft.Office.Interop.Excel.Application xlApp =
new Microsoft.Office.Interop.Excel.Application();
if (xlApp == null)
{
MessageBox.Show("无法创建Excel对象,您的电脑可能未安装Excel");
return;
}
Microsoft.Office.Interop.Excel.Range range;
Microsoft.Office.Interop.Excel.Workbooks workbooks = xlApp.Workbooks;
Microsoft.Office.Interop.Excel.Workbook workbook =
workbooks.Add(Microsoft.Office.Interop.Excel.XlWBATemplate.xlWBATWorksheet);
Microsoft.Office.Interop.Excel.Worksheet worksheet =
(Microsoft.Office.Interop.Excel.Worksheet)workbook.Worksheets[1];//取得sheet1
//写入标题
for (int i = 0; i < myGrid.ColumnCount; i++)
{ worksheet.Cells[1, i + 1] = myGrid.Columns[i].HeaderText; }
//写入数值
for (int r = 0; r < myGrid.Rows.Count; r++)
{
for (int i = 0; i < myGrid.ColumnCount; i++)
{
worksheet.Cells[r + 2, i + 1] = myGrid.Rows[r].Cells[i].Value;
}
System.Windows.Forms.Application.DoEvents();
}
worksheet.Columns.EntireColumn.AutoFit();//列宽自适应
xlApp.Cells.HorizontalAlignment = Microsoft.Office.Interop.Excel.Constants.xlCenter; //全局居中对齐
xlApp.DisplayAlerts = false;
int sum = 2;
for (int i = 0; i < sql.RootCount.Count; i++)
{
int temp = sql.RootCount[i];
if (temp > 1)
{
/*合并单元格*/
range = worksheet.get_Range("A" + sum.ToString(), "A" + (sum + temp - 1).ToString());
range.Merge(false);
range = worksheet.get_Range("B" + sum.ToString(), "B" + (sum + temp - 1).ToString());
range.Merge(false);
sum += temp;
}
else
sum++;
}
MessageBox.Show(fileName + "资料保存成功", "提示", MessageBoxButtons.OK);
if (saveFileName != "")
{
try
{
workbook.Saved = true;
workbook.SaveCopyAs(saveFileName); //fileSaved = true;
}
catch (Exception ex)
{//fileSaved = false;
MessageBox.Show("导出文件时出错,文件可能正被打开!\n" + ex.Message);
}
}
xlApp.Quit();
GC.Collect();//强行销毁
}
private void ImportExcel(object sender, EventArgs e)
{
string fileName = "";
string openFileName = "";
OpenFileDialog openDialog = new OpenFileDialog();
openDialog.DefaultExt = "xlsx";
openDialog.Filter = "Excel文件|*.xlsx";
openDialog.FileName = fileName;
openDialog.ShowDialog();
openFileName = openDialog.FileName;
if (openFileName.IndexOf(":") < 0) return; //被点了取消
if (MessageBox.Show("导入Excel会清除原数据库中的所有内容!是否继续?", "注意", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == DialogResult.OK)
{
Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
if (xlApp == null)
{
MessageBox.Show("无法创建Excel对象,您的电脑可能未安装Excel");
return;
}
object missing = System.Reflection.Missing.Value;
Microsoft.Office.Interop.Excel.Workbooks workbook = xlApp.Workbooks;
workbook.Open(openFileName, missing, true, missing, missing, missing,
missing, missing, missing, true, missing, missing, missing, missing, missing);
Microsoft.Office.Interop.Excel.Worksheet worksheet = (Microsoft.Office.Interop.Excel.Worksheet)xlApp.Worksheets.get_Item(1);
int rows = worksheet.UsedRange.Rows.Count;
int columns = worksheet.UsedRange.Columns.Count;
if(columns != 5)
{
MessageBox.Show("Excel内容格式不正确,请导入正确格式的表格");
return;
}
string TableName = worksheet.Name;
MainTable.sql.ClearDatabase();
for (int i = 2; i < rows+1; i++)
{
string name = Convert.ToString(((Excel.Range)worksheet.Cells[i,1]).Value2);
string score = Convert.ToString(((Excel.Range)worksheet.Cells[i,2]).Value2);
if(name != null)
{
MainTable.sql.ImportExcelData(name, score, null, null);
}
}
for (int j = 2; j < rows + 1; j++)
{
string name = Convert.ToString(((Excel.Range)worksheet.Cells[ j , 3 ]).Value2);
string score = Convert.ToString(((Excel.Range)worksheet.Cells[ j , 4 ]).Value2);
string detail = Convert.ToString(((Excel.Range)worksheet.Cells[j, 5]).Value2);
string upname = null;
int i = 0;
while ( upname == null)
{
upname = Convert.ToString(((Excel.Range)worksheet.Cells[j - i, 1]).Value2);
i++;
}
if (name != null)
{
MainTable.sql.ImportExcelData(name, score, detail,upname);
}
}
MessageBox.Show("导入完成!");
xlApp.Quit();
GC.Collect();//强行销毁
}
else
{
return;
}
}
1. Excel单元格合并
以图片为例,若想合并A2-A4单元格的内容,运行如下代码:
range = worksheet.get_Range("A2" "A4" )); //范围选择:A1-A4
range.Merge(false); //按默认设置合并
2. 单元格居中
xlApp.Cells.HorizontalAlignment = Microsoft.Office.Interop.Excel.Constants.xlCenter; //全局居中对齐
3. 单元格合并后,运行会弹出Excel提示:合并单元格时,仅保留左上角单元格的值,而放弃其他值。
合并一行就会弹一次,很烦,不想让它显示。运行下面代码解决:
xlApp.DisplayAlerts = false; //关闭程序的提醒