C# winform打印excel的方法
前言
c#做winform程序要求生成并打印Excel报告,为了不安装Office相应组件,我选择了NPOI来生成Excel报告,用winform的PrintDocument控件来触发打印操作,而难点在于如何将excel转换成Graphics对象,在NPOI中我只找到了excel打印的设置(如横向/纵向),还需要打开excel去触发打印操作,但项目要求是一次性直接实现打印,要用PrintDocument控件而不是再去操作excel。不得已重新搜索,发现了类库Spire.xls,最终实现了要求。有什么错误或更简洁的方法还请广大博友不吝赐教。
思路
用npoi生成Excel=》用spire.xls转换成图片.png=》获取生成的图片,利用Graphic的drawimage方法对图片进行操作,当然了,如果不介意的话,可以不对图片进行操作:)=》使用printDocument控件的print方法实现打印(当然这里可以直接用spire.xls直接生成Excel,但是Spire.xls的免费版本有每个sheet最多有150行的限制)
知识点
【0】NPOI使用方法
下载:http://npoi.codeplex.com/releases/
【1】winform的printDocument控件
参考:https://docs.microsoft.com/en-us/dotnet/framework/winforms/advanced/how-to-print-a-multi-page-text-file-in-windows-forms
理解:
PrintDocument控件的作用是定义一个向打印机发送输出的对象,有BeginPrint,PrintPage,EndPrint方法,当执行printdocument.Print()语句时,会检查是否存在BeginPrint方法,存在则先调用。然后调用PrintPage方法,该方法会向PrintPageEcentArgs类中获得一个空白的Graphics对象,我们可以对Graphics对象进行操作(可以理解对画布进行绘制,Graphics对象有内置的类似DrawString,DrawPie的方法),在PrintPage方法的最后,会向打印设备发送这个Graphics对象。打印设备完成打印后,会检查是否存在EndPrint方法,存在则调用。
【2】spire.xls使用方法
参考:.NET读写Excel工具Spire.Xls使用入门教程(1)
具体代码
【1】winform使用的打印控件介绍
使用的插件截图
printDocument1作用:定义一个向打印机发送输出的对象
printPreviewDialog1作用:显示一个对话框,向用户显示关联文档打印的样子
printDialog1作用:显示一个对话框,允许用户选择打印机并选择其他打印选项(如分数,纸张方向)
【2】代码展示
“直接打印”按钮的后台设置
privatevoidDirectPrint_Click(objectsender,EventArgse)
{
isprint=false;
GenerateExcel_Click(sender,e);//使用NPOI生成excel
if(newsavefilepath!=""&&isprint==true)
{
isprint=false;
ChangeExcel2Image(newsavefilepath);//利用Spire将excel转换成图片
if(printDialog1.ShowDialog()==DialogResult.OK)
{
printDocument1.Print();//打印
}
}
}
"生成excel"按钮后台设置
privatevoidGenerate_Click(objectsender,EventArgse)
{
CreateExcel();//使用NPOI生成excel内容
SaveFileDialogsavedialog=newSaveFileDialog();//弹出让用户选择excel保存路径的窗口
savedialog.Filter="excelfiles(*.xlsx)|*.xlsx|Allfiles(*.*)|*.*";
savedialog.RestoreDirectory=true;
savedialog.FileName=string.Format("销售订单审批单{0}",DateTime.Now.ToString("yyyyMMddHHmm"));
if(savedialog.ShowDialog()==DialogResult.OK)
{
//newsavefilepath是excel的保存路径
newsavefilepath=savedialog.FileName.ToString().Trim();
using(FileStreamnewfs=newFileStream(newsavefilepath,FileMode.Create,FileAccess.ReadWrite))
{
singlexssfwk.Write(newfs);//将生成的excel写入用户选择保存的文件路径中
newfs.Close();
}
}
}
CreateExcel()方法举例
usingNPOI.XSSF.UserModel;
XSSFWorkbooksinglexssfwk;
//注意,不同的NPOI版本调用的方法不一致,这里使用的版本是2.1.3.1
privatevoidCreatExcel()
{
//获取模板excel的路径
stringstr=System.Environment.CurrentDirectory+"\\XXXX.xlsx";
if(File.Exists(str))
{
using(FileStreamfs=newFileStream(str,FileMode.Open,FileAccess.Read))
{
singlexssfwk=newXSSFWorkbook(fs);
fs.Close();
}
//获取表
XSSFSheetxssfsheet=(XSSFSheet)singlexssfwk.GetSheetAt(0);
//创建行
XSSFRowxssfrow1=(XSSFRow)xssfsheet.GetRow(1);
//设置单元格内容
xssfrow1.GetCell(0).SetCellValue("...");
......
}
else{
......
}
}
ChangeExcel2Image()方法举例
usingSpire.Xls;
publicvoidChangeExcel2Image(stringfilename)
{
Workbookworkbook=newWorkbook();
workbook.LoadFromFile(filename);
Worksheetsheet=workbook.Worksheets[0];
sheet.SaveToImage(imagepath);//图片后缀.bmp,imagepath自己设置
}
执行printDocument1.Print()的方法会调用printDocument1_PrintPage方法
//在PrintPage方法中写截取图片的代码
privatevoidprintDocument1_PrintPage(objectsender,System.Drawing.Printing.PrintPageEventArgse)
{
#region如果不需要截取图片,可以不用写以下代码
GC.Collect();
Graphicsg=e.Graphics;
//imagepath是指excel转成的图片的路径
using(Bitmapbitmap=newdBitmap(imagepath))
{
//如何截取自己摸索
Rectanglenewarea=newRectangle();
newarea.X=0;
newarea.Y=50;
newarea.Width=bitmap.Width;
newarea.Height=bitmap.Height-120;
using(Bitmapnewbitmap=bitmap.Clone(newarea,bitmap.PixelFormat))
{
g.DrawImage(newbitmap,0,0,newbitmap.Width-200,newbitmap.Height-150);
}
}
#endregion
}
备注:关于预览的设置,关键在于printDocument1是个全局对象,直接设置printPreviewDialog1.Document=printDocument1;printPreviewDialog1.ShowDialog();即可,这个的原理没有研究,反正这样设置后,只要你处理好内容,就能在预览中看到。
总结
以上就是我实现c#winform打印excel的经过,或许这只是一种比较冗杂的方法,如果有大佬有更精简的方法,请不吝赐教。如有错误,也请不吝赐教。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。