C# winform打印excel的方法
前言
c#做winform程序要求生成并打印Excel報告,為了不安裝Office相應(yīng)組件,我選擇了NPOI來生成Excel報告,用winform的PrintDocument控件來觸發(fā)打印操作,而難點在于如何將excel轉(zhuǎn)換成Graphics對象,在NPOI中我只找到了excel打印的設(shè)置(如橫向/縱向),還需要打開excel去觸發(fā)打印操作,但項目要求是一次性直接實現(xiàn)打印,要用PrintDocument控件而不是再去操作excel。不得已重新搜索,發(fā)現(xiàn)了類庫Spire.xls,最終實現(xiàn)了要求。有什么錯誤或更簡潔的方法還請廣大博友不吝賜教。
思路
用npoi生成Excel =》 用spire.xls轉(zhuǎn)換成圖片.png =》 獲取生成的圖片,利用Graphic的drawimage方法對圖片進(jìn)行操作,當(dāng)然了,如果不介意的話,可以不對圖片進(jìn)行操作:) =》使用printDocument控件的print方法實現(xiàn)打印( 當(dāng)然這里可以直接用spire.xls直接生成Excel,但是Spire.xls的免費版本有每個sheet最多有150行的限制 )
知識點
【0】NPOI使用方法
下載:http://npoi.codeplex.com/releases/
【1】winform的printDocument控件
理解:
PrintDocument控件的作用是定義一個向打印機(jī)發(fā)送輸出的對象,有BeginPrint,PrintPage,EndPrint方法,當(dāng)執(zhí)行printdocument.Print()語句時,會檢查是否存在BeginPrint方法,存在則先調(diào)用。然后調(diào)用PrintPage方法,該方法會向PrintPageEcentArgs類中獲得一個空白的Graphics對象,我們可以對Graphics對象進(jìn)行操作(可以理解對畫布進(jìn)行繪制,Graphics對象有內(nèi)置的類似DrawString,DrawPie的方法),在PrintPage方法的最后,會向打印設(shè)備發(fā)送這個Graphics對象。打印設(shè)備完成打印后,會檢查是否存在EndPrint方法,存在則調(diào)用。
【2】spire.xls使用方法
參考:.NET讀寫Excel工具Spire.Xls使用入門教程(1)
具體代碼
【1】winform使用的打印控件介紹
使用的插件截圖
printDocument1作用:定義一個向打印機(jī)發(fā)送輸出的對象
printPreviewDialog1作用:顯示一個對話框,向用戶顯示關(guān)聯(lián)文檔打印的樣子
printDialog1作用:顯示一個對話框,允許用戶選擇打印機(jī)并選擇其他打印選項(如分?jǐn)?shù),紙張方向)
【2】代碼展示
“直接打印” 按鈕的后臺設(shè)置
private void DirectPrint_Click(object sender, EventArgs e) { isprint = false; GenerateExcel_Click(sender, e); //使用NPOI生成excel if (newsavefilepath != "" && isprint==true) { isprint = false; ChangeExcel2Image(newsavefilepath); //利用Spire將excel轉(zhuǎn)換成圖片 if (printDialog1.ShowDialog() == DialogResult.OK) { printDocument1.Print(); //打印 } } }
"生成excel" 按鈕后臺設(shè)置
private void Generate_Click(object sender, EventArgs e) { CreateExcel(); //使用NPOI生成excel內(nèi)容 SaveFileDialog savedialog = new SaveFileDialog(); //彈出讓用戶選擇excel保存路徑的窗口 savedialog.Filter = " excel files(*.xlsx)|*.xlsx|All files(*.*)|*.*"; 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 (FileStream newfs = new FileStream(newsavefilepath, FileMode.Create, FileAccess.ReadWrite)) { singlexssfwk.Write(newfs); //將生成的excel寫入用戶選擇保存的文件路徑中 newfs.Close(); } } }
CreateExcel()方法舉例
using NPOI.XSSF.UserModel; XSSFWorkbook singlexssfwk; //注意,不同的NPOI版本調(diào)用的方法不一致,這里使用的版本是2.1.3.1 private void CreatExcel() { //獲取模板excel的路徑 string str = System.Environment.CurrentDirectory + "\\XXXX.xlsx"; if (File.Exists(str)) { using (FileStream fs = new FileStream(str, FileMode.Open, FileAccess.Read)) { singlexssfwk = new XSSFWorkbook(fs); fs.Close(); } //獲取表 XSSFSheet xssfsheet = (XSSFSheet)singlexssfwk.GetSheetAt(0); //創(chuàng)建行 XSSFRow xssfrow1 = (XSSFRow)xssfsheet.GetRow(1); //設(shè)置單元格內(nèi)容 xssfrow1.GetCell(0).SetCellValue("..."); ... ... } else{ ... ... } }
ChangeExcel2Image()方法舉例
using Spire.Xls; public void ChangeExcel2Image(string filename) { Workbook workbook = new Workbook(); workbook.LoadFromFile(filename); Worksheet sheet = workbook.Worksheets[0]; sheet.SaveToImage(imagepath); //圖片后綴.bmp ,imagepath自己設(shè)置 }
執(zhí)行printDocument1.Print()的方法會調(diào)用printDocument1_PrintPage方法
//在PrintPage方法中寫截取圖片 的代碼 private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e) { #region 如果不需要截取圖片,可以不用寫以下代碼 GC.Collect(); Graphics g = e.Graphics; //imagepath是指 excel轉(zhuǎn)成的圖片的路徑 using (Bitmap bitmap = new dBitmap(imagepath)) { //如何截取自己摸索 Rectangle newarea = new Rectangle(); newarea.X = 0; newarea.Y = 50; newarea.Width = bitmap.Width; newarea.Height = bitmap.Height - 120; using (Bitmap newbitmap = bitmap.Clone(newarea, bitmap.PixelFormat)) { g.DrawImage(newbitmap, 0, 0, newbitmap.Width - 200, newbitmap.Height - 150); } } #endregion }
備注:關(guān)于預(yù)覽的設(shè)置,關(guān)鍵在于printDocument1是個全局對象,直接設(shè)置printPreviewDialog1.Document = printDocument1; printPreviewDialog1.ShowDialog();即可,這個的原理沒有研究,反正這樣設(shè)置后,只要你處理好內(nèi)容,就能在預(yù)覽中看到。
總結(jié)
以上就是我實現(xiàn)c# winform打印excel的經(jīng)過,或許這只是一種比較冗雜的方法,如果有大佬有更精簡的方法,請不吝賜教。如有錯誤,也請不吝賜教。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- c# 實現(xiàn)打印機(jī)狀態(tài)查詢與阻塞打印
- c#使用Aspose打印文件的示例
- C# 調(diào)用exe傳參,并獲取打印值的實例
- 如何利用C#打印九九乘法表
- c# winform 解決PictureBox 無法打印全部圖片的問題
- C#操作Word打印的示例
- C#操作excel打印的示例
- C# 打印網(wǎng)頁不顯示頁眉頁腳的實現(xiàn)方法
- C#實現(xiàn)掃描槍掃描二維碼并打印(實例代碼)
- C#利用PrintDocument定制打印單據(jù)的小例子
- C#打印PDF文檔的10種方法(小結(jié))
- C# TSC打印二維碼和條形碼的實現(xiàn)方法
- c# 如何實現(xiàn)web打印插件
相關(guān)文章
ASP.NET Core Kestrel 中使用 HTTPS (SSL)
這篇文章主要為大家詳細(xì)介紹了ASP.NET Core Kestrel 中使用 HTTPS(SSL)的相關(guān)資料,感興趣的小伙伴們可以參考一下2016-09-09ASP.NET DataTable去掉重復(fù)行的2種方法
這篇文章主要介紹了ASP.NET DataTable去掉重復(fù)行的2種方法,本文直接給出去重代碼,需要的朋友可以參考下2015-02-02ASP.NET簡單獲取服務(wù)端和客戶端計算機(jī)名稱的方法
這篇文章主要介紹了ASP.NET簡單獲取服務(wù)端和客戶端計算機(jī)名稱的方法,涉及asp.net獲取服務(wù)器端計算機(jī)名以及根據(jù)IP獲取客戶端主機(jī)名的相關(guān)技巧,需要的朋友可以參考下2016-08-08Razor TagHelper實現(xiàn)Markdown轉(zhuǎn)HTML的方法
下面小編就為大家分享一篇Razor TagHelper實現(xiàn)Markdown轉(zhuǎn)HTML的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2017-12-12Asp.net Core中如何使用中間件來管理websocket
這篇文章主要給大家介紹了關(guān)于Asp.net Core中如何使用中間件來管理websocket的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-09-09ASP.NET與MySQL數(shù)據(jù)庫簡明圖示入門教程
ASP.NET與MySQL數(shù)據(jù)庫簡明圖示入門教程...2006-09-09