.net core 動態生成帶有圖片的word文檔


    最近客戶突然讓整理所有施工站點的完工照片,他們需要留檔,所以不想通過平台直接查看,想把所有完工照片,按照操作步驟把圖片放在word文檔中。一個市一千多個站點要用人工去做,那一個人也得一個月。所以就寫了一個簡單的程序,動態生成word的方式。信息化統計肯定比人效率高。

   我選擇了NPOI插件做的,因為也就是一次性,我就直接用控制台簡單的實現了一下。不多說直接上代碼:

  這次的邏輯是記錄鄭州市各個區域的站點。所以要分區域見文件夾,各個站點的word文檔就放在各個區域的文件夾下。

using NPOI.OpenXmlFormats.Wordprocessing;
using NPOI.Util;
using NPOI.XWPF.UserModel;
using System;
using System.Data;
using System.Drawing;
using System.IO;
using System.Net;
using System.Threading.Tasks;

namespace WordExportDemo
{
    internal class Program
    {
        private static void Main(string[] args)
        {
           
            DataTable dtlist = SqlHelper.Query(" SELECT PTId,PId,TaskName,TaskLable,TaskTemplateId ,JZ_Id ,JZ_Type,(select AreaName from Sys_Area where AreaCode=JZ_AREAID) AreaName FROM Project_Task where TaskType=2 and PId=8 and JZ_Type!=3 and State>0 and JZ_CityID=410100");
            foreach (DataRow item in dtlist.Rows)
            {
              
                    string areaname = item["AreaName"].ToString().Trim();//城市名稱
                    string taskName = item["TaskName"].ToString().Trim();//任務名稱,或者城市名稱
                    int Temple = int.Parse(item["PTId"].ToString());//任務模板id

                    string path = System.AppDomain.CurrentDomain.BaseDirectory + "鄭州市\\" + areaname;//拼接路徑
                    CreatePath(path);//判斷路徑是否存在,不存在先建路徑
                    path = path + "\\" + taskName + ".docx";//給word文檔命名
                    XWPFDocument doc = new XWPFDocument();//創建一個word文檔

                    // 添加段落
                    XWPFParagraph gp = doc.CreateParagraph();
                    gp.Alignment = ParagraphAlignment.CENTER;//水平居中
                    XWPFRun gr = gp.CreateRun();
                    gp = doc.CreateParagraph();
                    gr = gp.CreateRun();
                    gr.GetCTR().AddNewRPr().AddNewRFonts().ascii = "黑體";
                    gr.GetCTR().AddNewRPr().AddNewRFonts().eastAsia = "黑體";
                    gr.GetCTR().AddNewRPr().AddNewRFonts().hint = ST_Hint.eastAsia;
                    gr.GetCTR().AddNewRPr().AddNewSz().val = (ulong)42;//2號字體
                    gr.GetCTR().AddNewRPr().AddNewSzCs().val = (ulong)42;
                    gr.GetCTR().AddNewRPr().AddNewB().val = true; //加粗
                    gr.GetCTR().AddNewRPr().AddNewColor().val = "red";//字體顏色
                    gr.SetText("站點名稱:" + taskName); 
                    DataTable dttemple = SqlHelper.Query("SELECT  Id,Description ,AddTime ,TempStepId,(select Description from Project_TemplateStep where Id=TempStepId) StepDescription ,OrderNum FROM Project_TaskStep where PTId=" + Temple + " order by OrderNum asc");
                    foreach (DataRow item1 in dttemple.Rows)
                    {
                        int tempid = int.Parse(item1["Id"].ToString());//步驟Id
                        string TempName = item1["StepDescription"].ToString();//步驟名稱
                        int step = int.Parse(item1["OrderNum"].ToString());//步驟數
                        string stepDescrip = item1["Description"].ToString();//步驟描述
                                                                             /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                                                                             //添加任務步驟描述
                        gp = doc.CreateParagraph();
                        gr = gp.CreateRun();
                        CT_RPr rpr = gr.GetCTR().AddNewRPr();
                        CT_Fonts rfonts = rpr.AddNewRFonts();
                        rfonts.ascii = "宋體";
                        rfonts.eastAsia = "宋體";
                        rpr.AddNewSz().val = (ulong)21;//5號字體
                        rpr.AddNewSzCs().val = (ulong)21;
                        gr.SetText("步驟" + step + ":" + TempName + " 描述:" + stepDescrip);
                        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                        DataTable dtimg = SqlHelper.Query("SELECT TableName,Path,AddTime FROM Project_TaskFile where TableName='Project_TaskStep' and TableKey=" + tempid + "   order by AddTime asc");
                        gp = doc.CreateParagraph();
                        gr = gp.CreateRun();
                        foreach (DataRow item3 in dtimg.Rows)
                        {
                            string s = "ip" + item3["Path"].ToString();
                            try
                            {
                                HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://ip" + item3["Path"].ToString());
                                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                                Stream imgstream = response.GetResponseStream();//獲取圖片的流
                                Image image = Image.FromStream(imgstream);//將流轉化成Image,這樣做是為了得到原圖的寬(image.Width)和高(image.Height),放在word中可以通過寬和高等比縮放,這樣就可以保證圖片不變形。
                                gr.AddPicture(ImgToStream(image), (int)PictureType.PNG, "1.png", image.Width * 800, image.Height * 800);//ImgToTream(image)
                            }
                            catch (Exception e)
                            {
                                Console.WriteLine("---------------------------------------------------------------------------------------------------");
                                Console.WriteLine("區域:" + areaname + "--任務名稱:" + taskName + "--" + "步驟" + tempid + "--這個圖片路徑有異常:URL=" + s);
                                Console.WriteLine("---------------------------------------------------------------------------------------------------");
                            }




                        }
                    }
                    using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
                    {
                        doc.Write(fs);
                        Console.WriteLine("生成word成功");
                    }
               
              
            }
          

         
            Console.ReadKey();
        }
     
       
    }

}

下面是遠程下載圖片並且將圖片插入word中,

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://ip" + item3["Path"].ToString());
                                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                                Stream imgstream = response.GetResponseStream();//獲取圖片的流
                                Image image = Image.FromStream(imgstream);
                                gr.AddPicture(ImgToStream(image), (int)PictureType.PNG, "1.png", image.Width * 800, image.Height * 800);

AddPicture這個是NPOI里面的程序集,他提供了傳入圖片的方式是一個Stream流:  pictureData:表示傳入一個圖片的流。   pictureType:表示圖片的類型:png,jpeg..... filename:圖片的名字.width:圖片的寬。height:圖片的高。

 

 或許有人會問,既然傳入的是一個流,為什么還有用Imag轉化成流在傳入,遠程下載的時候就是一個流,直接傳入不就行了。我一開始也是這樣做的。但是我必須要先轉換成Image,不然我無法得到原圖的寬和高。有人或許還會問,那轉成Image也不影響把流傳入進去。我試過了,這個流一旦轉換成Image之后,這個流的長度就是0,如果作為參數傳入AddPicture方法會報異常。我也試了先把流轉換成字節存起來,然后利用字節轉換成Image和Stream流,但是也失敗了,所有我最后選擇先用Stream流轉換成Image得到寬和高后再把Image轉換為字節,通過字節在轉換成流,結果成功了。

判斷路徑是否存在的方法

  /// <summary>
        /// 創建目錄,如果目錄不存在就創建,存在則直接返回。
        /// </summary>
        /// <param name="path"></param>
        public static string CreatePath(string strPath)
        {
            if (!System.IO.Directory.Exists(strPath))
                System.IO.Directory.CreateDirectory(strPath);
            return strPath;
        }

圖片轉換成字節流

 /// <summary>
        /// 圖片轉換成字節流
        /// </summary>
        /// <param name="img">要轉換的Image對象</param>
        /// <returns>轉換后返回的字節流</returns>
        public static Stream ImgToStream(Image img)
        {
            byte[] imgByte = ImgToByt(img);
            //img.Save(ms, img.RawFormat);//System.Drawing.Imaging.ImageFormat.Jpeg
            Stream stream = new MemoryStream(imgByte);
            return stream;
        }
   /// <summary>
        /// 圖片轉換成字節流
        /// </summary>
        /// <param name="img">要轉換的Image對象</param>
        /// <returns>轉換后返回的字節流</returns>
        public static byte[] ImgToByt(Image img)
        {
            MemoryStream ms = new MemoryStream();
            byte[] imagedata = null;
            img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
            imagedata = ms.GetBuffer();
            return imagedata;
        }

運行后結果:

 

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM