User Tools

Site Tools

blog:2024-07-18_share_c_winform印製excel_使用npoi_spire.xls_printdocument直接印製excel



2024-07-18 Share: c# winform印製excel(使用NPOI+Spire.xls+PrintDocument直接印製excel)

Local Backup

前言

  • 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行的限制 )

知識點

具體代碼

  • 【1】winform使用的列印控制項介紹
    • printDocument1作用:定義一個向印表機發送輸出的對象
    • printPreviewDialog1作用:顯示一個對話方塊,向使用者顯示關聯文檔列印的樣子
    • printDialog1作用:顯示一個對話方塊,允許使用者選擇印表機並選擇其他列印選項(如分數,紙張方向)
  • 【2】代碼展示
    • “直接列印” 按鈕的後台設定
      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轉換成圖片
          if (printDialog1.ShowDialog() == DialogResult.OK)
          {                     
            printDocument1.Print();   //列印                
          }            
        }          
      }
  • “產生excel” 按鈕後台設定
    • private void Generate_Click(object sender, EventArgs e)        
      {            
        CreateExcel(); //使用NPOI產生excel內容            
        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版本調用的方法不一致,這裡使用的版本是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);
          //建立行
          XSSFRow xssfrow1 = (XSSFRow)xssfsheet.GetRow(1);
          //設定儲存格內容
          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自己設定
      }
  • 執行printDocument1.Print()的方法會調用printDocument1_PrintPage方法
    //在PrintPage方法中寫截取圖片 的代碼 
    private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
    {
    #region 如果不需要截取圖片,可以不用寫以下代碼
      GC.Collect();
      Graphics g = e.Graphics; //imagepath是指 excel轉成的圖片的路徑
      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        
    }
  • 備忘:關於預覽的設定,關鍵在於printDocument1是個全域對象,直接設定printPreviewDialog1.Document = printDocument1; printPreviewDialog1.ShowDialog();即可,這個的原理沒有研究,反正這樣設定後,只要你處理好內容,就能在預覽中看到。

TAGS

  • 36 person(s) visited this page until now.

Permalink blog/2024-07-18_share_c_winform印製excel_使用npoi_spire.xls_printdocument直接印製excel.txt · Last modified: 2024/07/19 12:55 by jethro

oeffentlich