.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:图片的名字.图片的宽。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;
        }

运行后结果:

 

.Net Core
原文地址:https://www.cnblogs.com/zpy1993-09/p/14976202.html