• .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
  • 相关阅读:
    AJPFX解析成员变量和局部变量
    AJPFX关于Java Object类常用方法小总结
    AJPFX关于面向对象中的对象初始化整理,综合子父类、代码块等等
    AJPFX总结FileWriter类的write方法
    AJPFX总结java创建线程的三种方式及其对比
    java android中日期时间 问题总结
    安卓开发——ListView控件(初始化ListView、列表刷新、长按添加menu)
    android开发分辨率适配总结
    activity生命周期实例(不同启动模式)
    ViewPage最全解析
  • 原文地址:https://www.cnblogs.com/zpy1993-09/p/14976202.html
Copyright © 2020-2023  润新知