填充word模版数据,生成pdf文件,打水印
很多时候,我们会有这么一个需求,我需要根据一个word文档或者excel模版来导出数据。比如一个word合同模版,要根据具体的业务需求,自动填充如客户名称,项目名称等信息。
向word文档中填充数据,一般采用的是标签的形式,循环标签名,找到数据源的对象属性,取值赋值。对于word文档中列表的处理,相对比较耗时点。这里摘取几段核心代码块。
/// <summary> /// 根据标签 /// 填充word文档信息 /// </summary> /// <param name="sourceFile">源文件路径</param> /// <param name="targetFile">保存文件路径地址</param> /// <param name="jObject">填充的数据源</param> public static void FillWordData(string sourceFile,string targetFile, JObject jObject) { Aspose.Words.Document doc = new Aspose.Words.Document(sourceFile); //获取word文档中设计的标签列表 BookmarkCollection bookmarkCollection = doc.Range.Bookmarks; //循环标签列表 //根据标签name 从数据源jObject中取值 写入标签text foreach (Aspose.Words.Bookmark bookmark in bookmarkCollection) { if (bookmark.Name != "_GoBack") if (bookmark.Name == "dlqx") { DateTime dateTimeStart = Convert.ToDateTime(jObject["dlqx__c"].ToString()); DateTime dateTimeEnd = Convert.ToDateTime(jObject["dlqxjs__c"].ToString()); bookmark.Text = $"{dateTimeStart.Year}年{dateTimeStart.Month}月{dateTimeStart.Day}日至{dateTimeEnd.Year}年{dateTimeEnd.Month}月{dateTimeEnd.Day}日"; } else if (bookmark.Name == "szsc__c") { string szsc_c = ((JArray)jObject["szsc__c"])[0].ToString(); if (szsc_c == "option1") bookmark.Text = "全国"; if (szsc_c == "other") bookmark.Text = "其他"; } } //保存到本地 以pdf格式 doc.Save(targetFile, Aspose.Words.SaveFormat.Pdf); } /// <summary> /// 填充word文档中的 /// table表格 /// 可以新增表格行 写入行记录 /// </summary> /// <param name="sourceFile"></param> /// <param name="targetFile"></param> /// <param name="tcJarray"></param> public static void FillWordTableData(string sourceFile,string targetFile, JArray tcJarray) { Aspose.Words.Document doc = new Aspose.Words.Document(sourceFile); DocumentBuilder builder = new DocumentBuilder(doc); //获取word模板中所有表格table NodeCollection allTables = doc.GetChildNodes(NodeType.Table, true); //拿到word文档中的第一个表格 下标从零 开始 //同理 第二个表格 下标就是 1 以此类推 Aspose.Words.Tables.Table tcTable = allTables[0] as Aspose.Words.Tables.Table;//拿到第1个表格 /* * 一般表格第一行 都是表头 * 需要填充的往往是从第二行开始 具体根据实际业务需要来 * 所以我这里在模版中 先把需要填充的行 * 只保留一行 * 然后复制该行 * 不断的将复制的行 * 按照数据源的行数进行插入 */ for (int w = 0; w < tcJarray.Count - 1; w++) { //获取第二行 下标从零开始 这行是需要不断重复填充数据的行 var pastRow = tcTable.Rows[1]; var newRow = pastRow.Clone(true); tcTable.Rows.Insert(w + 2, newRow); } //循环数据源 填充上面新增的行数据 for (int p = 0; p < tcJarray.Count; p++) { /** * 将指针移动到 * 第一个表(第一个参数 下标从零开始) 同理 第二个表格 下标就换成 1 以此类推 * 的 第几行 * 例如 p=0的时候 移动到下标为1的行 (也就是需要填充数据的第一行 表头下标是零) * 第三个参数 列下标 0 为第一列 * 第四个参数我这里没管 * */ builder.MoveToCell(0, 1 + p, 0, 0); /** * 写入值 * 我这里 * 第一列写入的行号 * 比如 1 2 3 ... */ builder.Write((p + 1).ToString()); if (tcJarray[p]["tcmcwb__c"] != null) { /** * 指针移动到 * 第一个表格的第1+p 行 * 第一列 */ builder.MoveToCell(0, 1 + p, 1, 0); builder.Write(tcJarray[p]["tcmcwb__c"].ToString()); } if (tcJarray[p]["jsj__c"] != null) { builder.MoveToCell(0, 1 + p, 2, 0); builder.Write(tcJarray[p]["jsj__c"].ToString()); } } //以pdf形式保存到本地 doc.Save(targetFile, Aspose.Words.SaveFormat.Pdf); } /// <summary> /// 加多图片水印 /// </summary> /// <param name="sourceFile">源pdf文件的流形成的字节数组</param> /// <param name="outputfilepath"></param> /// <param name="ModelPicName">第一个水印图片路径地址</param> /// <param name="signPng">第二个水印图片路径地址</param> /// <param name="top"></param> /// <param name="left"></param> /// <returns></returns> public static bool PDFWatermark(byte[] sourceFile, string outputfilepath, string ModelPicName, string signPng, float top, float left) { //throw new NotImplementedException(); PdfReader pdfReader = null; PdfStamper pdfStamper = null; try { pdfReader = new PdfReader(sourceFile); int numberOfPages = pdfReader.NumberOfPages; iTextSharp.text.Rectangle psize = pdfReader.GetPageSize(1); float width = psize.Width; float height = psize.Height; pdfStamper = new PdfStamper(pdfReader, new FileStream(outputfilepath, FileMode.Create)); PdfContentByte waterMarkContent; // 设置水印透明度 PdfGState gs = new PdfGState(); // 设置笔触字体不透明度为0.4f //透明度 gs.FillOpacity = 0.2f; iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(ModelPicName); image.GrayFill = 20; image.Rotation = 95; //旋转 // image.RotationDegrees = 30; //旋转角度 image.ImageMask.GrayFill = 20; //指定颜色透明,如:白色 image.Transparency = new int[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; iTextSharp.text.Image signimage = iTextSharp.text.Image.GetInstance(signPng); signimage.GrayFill = 20; signimage.ImageMask.GrayFill = 20; //指定颜色透明,如:白色 image.Transparency = new int[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; //水印的位置 if (left < 0) { left = width / 2; } //image.SetAbsolutePosition(left, (height - image.Height) - top); //每一页加水印,也可以设置某一页加水印 for (int i = 1; i <= numberOfPages; i++) { // waterMarkContent = pdfStamper.GetUnderContent(i);//内容下层加水印 waterMarkContent = pdfStamper.GetOverContent(i);//内容上层加水印 waterMarkContent.SetGState(gs); image.SetAbsolutePosition(width / 2 - image.Width / 2, height / 3); waterMarkContent.AddImage(image); image.SetAbsolutePosition(width / 2 - image.Width / 2, height / 3 * 2); waterMarkContent.AddImage(image); signimage.SetAbsolutePosition(width / 2 + image.Width / 2, height / 12); waterMarkContent.AddImage(signimage); } //strMsg = "success"; return true; } catch (Exception ex) { throw ex; } finally { if (pdfStamper != null) pdfStamper.Close(); if (pdfReader != null) pdfReader.Close(); } }
完整代码下载地址:
链接:https://pan.baidu.com/s/1_PIXS3IyGIR_RXHhzKmh9A
提取码:1uft