当前位置:网站首页>使用Asponse.Words處理Word模板
使用Asponse.Words處理Word模板
2020-11-06 01:23:27 【itread01】
一.客戶需求
近期接到一個專案,在與客戶初步溝通後,客戶描述的需求聽起來也非常簡單,就是目前客戶需要在Excel錄入資料,然後把這些資料分別複製到多個Word的多個地方,除了單個值之外,還需要複製表格資料以及圖片資料,客戶覺得這麼操作一是容易出錯,二是重複操作的工作量太大。在初步瞭解使用者的需求之後,得知客戶需求的核心功能就是在Word中填充資料來源,需要填充資料的資料來源包括文字,表格以及圖片等,本文以此為出發點,重點介紹如何在Word中使用“域”來填充外部資料。
二.外掛選型
目前處理Word等Office文件型別的控制元件,微軟自帶的Com元件問題實在太多,一個比較麻煩的問題就是部分Com元件需要註冊,並且如果客戶端與開發電腦使用的Com元件版本不一致,還會出現各種問題,因此選擇了Asponse.words外掛,該軟體為收費外掛,具體的收費標準可以在官網進行檢視。
三.模板製作
利用Asponse進行資料填充,其實程式碼不難,核心的工作就是需要在Word模板中設定標記,也就是需要讓程式知道在什麼地方填充資料,目前做標記的方式有兩種,一種是使用書籤,一種是使用域。目前網上大多的案例都是使用書籤,但是在我實際開發的過程中,建議大家使用“域”,而不是使用書籤,原因有以下幾點:
1.書籤不能重複新增,比如我在第一個空白出需要插入資料來源“姓名”,在最後簽名處還要插入“姓名”,這個時候使用“域”的話可以在兩處都插入“姓名”域,但是如果使用書籤,需要設定不同的書籤名稱,生成資料來源的時候會增加工作量
2.書籤不能在文件中直觀的展示出來,如果插入書籤比較多,很容易造成混亂
此外,需要特別說明的是,製作書籤或者“域"的時候務必務必使用Word而不是WPS製作,因為目前發現的一個問題就是,使用WPS製作的書籤或者是”域“,在填充資料之後會自動增加一行空行,這個可能是WPS與Word的內部機制不同;還有一個技巧,在文件中使用Alt+F9,可以檢視到模板的各種域程式碼,如下圖所示:
四.插入書籤/域
1.插入書籤
2.插入域(插入->文件部件->域,選擇"MergeField")
五.實現程式碼
1.獲取文件
Aspose.Words.Document doc = new Aspose.Words.Document(filePath); Aspose.Words.DocumentBuilder builder = new Aspose.Words.DocumentBuilder(doc);
2.利用word模板填充資料
List<string> filedsValueList = new List<string>(); string[] filedsName =doc.MailMerge.GetFieldNames();//獲取文件中所有的域 for (int i = 0; i < filedsName.Length; i++) { if (dataTable.Columns.Contains(filedsName[i])) { filedsValueList.Add(dataTable.Rows[0][filedsName[i]].ToString()); } else { filedsValueList.Add(""); } }
//核心程式碼其實就是這一句,上面的都是組織資料來源
//引數是兩個陣列,第一個陣列是文件中所有”域“的名稱,第二個是所對應域的值 doc.MailMerge.Execute(filedsName, filedsValueList.ToArray());
3.插入圖片
插入圖片並不需要特殊的程式碼,而是需要對Word模板中的域做特殊設定,設定的方式為:
在彈出來的對話方塊中,把”域“名稱的前面加上"Image:",如下圖所示:
設定好之後,只需要將該域的值設定為圖片的路徑,即可在文件中展示圖片,如果需要在程式碼中控制圖片的大小,需要給文件繫結圖片處理的回撥事件,程式碼如下:
doc.MailMerge.FieldMergingCallback = new HandleMerFieldInsert();
4.設定圖片尺寸
在Asponse直接提供的方法中,沒有修改圖片尺寸的方法,但是可以重寫Asponse的IFieldMergingCallback類,用於設定圖片大小
class HandleMerFieldInsert : IFieldMergingCallback { //文字處理 void IFieldMergingCallback.FieldMerging(FieldMergingArgs e) { } //圖片處理 void IFieldMergingCallback.ImageFieldMerging(ImageFieldMergingArgs args) { Document doc = args.Document; DocumentBuilder builder = new DocumentBuilder(doc); builder.MoveToMergeField(args.FieldName); Shape shapeImage = builder.InsertImage(args.FieldValue.ToString()); //設定x,y座標和高寬. shapeImage .Left = 0; shapeImage .Top = 0; shapeImage .Width = 50; shapeImage .Height = 25; } }
5.填充表格
填充表格資料,需要在模板中先設定表格繫結資料的起始位置,然後在每一列中設定資料來源中的列名稱,具體步驟如下圖:
表格資料來源的起始標記為”TableStart“,結束標記為"TableEnd",設定好表格資料來源的起始與結束標記之後,再在每一列中單獨設定每一列需要繫結的欄位名稱即可,設定好的資料來源如下圖所示:
通過Alt+F9可以看到設定好的各種域的程式碼,如下圖所示:
設定好表格的各個域之後,通過如下程式碼完成對資料來源的填充:
dt.TableName = "UserInfo";//這裡的表格名稱必須和模板中表格的起始與結束源名稱相同
doc.MailMerge.ExecuteWithRegions(dt);
6.刪除表格及對應的佔位符
使用Asponse進行刪除的操作相對比較複雜,現有的業務是需要刪除模板中的某一個表格,但有個問題就是,在刪除了該表格之後,該表格所在頁面的佔位符還在,會導致生成的文件有一個空白頁,因此在刪除類似表格,圖片這種元素時,還需要刪除對應的段落佔位符
NodeCollection nodeCollection = doc.GetChildNodes(NodeType.Table, true);//獲取所有表格 foreach (Table table in nodeCollection) { if (table.GetText().Contains("AAAAAA") && table.GetText().Contains("BBBBBB"))//To Do:這裡通過獲取表格中的內容來判定是否為刪除的表格,應該還有更好的辦法 { Paragraph paragraph = (Paragraph)table.PreviousSibling; paragraph.Remove();//刪除段落 table.Remove();//刪除表格 } }
7.儲存帶密碼的PDF
Aspose.Words.Saving.PdfSaveOptions saveOption = new Aspose.Words.Saving.PdfSaveOptions(); saveOption.SaveFormat = Aspose.Words.SaveFormat.Pdf; PdfEncryptionDetails encryptionDetails = new PdfEncryptionDetails(pdfPwd, string.Empty, PdfEncryptionAlgorithm.RC4_128); encryptionDetails.Permissions = PdfPermissions.AllowAll; saveOption.EncryptionDetails = encryptionDetails; doc.Save(fullfilepath + ".pdf", saveOption);
8.刪除未被賦值的“域”
doc.MailMerge.DeleteFields();
寫在最後
至此,Asponse利用模板處理資料的常規方法總結完畢,對於直接使用Asponse的方法,在Word中通過硬編碼的方式增加表格建議不到萬不得已不要使用,因為增加表格需要控制表格本身的樣式,還需要控制單元格的樣式,並且對於複雜的文件,定位表格也會增加難度。
版权声明
本文为[itread01]所创,转载请带上原文链接,感谢
https://www.itread01.com/content/1604511124.html
边栏推荐
- C++ 数字、string和char*的转换
- C++学习——centos7上部署C++开发环境
- C++学习——一步步学会写Makefile
- C++学习——临时对象的产生与优化
- C++学习——对象的引用的用法
- C++编程经验(6):使用C++风格的类型转换
- Won the CKA + CKS certificate with the highest gold content in kubernetes in 31 days!
- C + + number, string and char * conversion
- C + + Learning -- capacity() and resize() in C + +
- C + + Learning -- about code performance optimization
猜你喜欢
-
C + + programming experience (6): using C + + style type conversion
-
Latest party and government work report ppt - Park ppt
-
在线身份证号码提取生日工具
-
Online ID number extraction birthday tool
-
️野指针?悬空指针?️ 一文带你搞懂!
-
Field pointer? Dangling pointer? This article will help you understand!
-
HCNA Routing&Switching之GVRP
-
GVRP of hcna Routing & Switching
-
Seq2Seq实现闲聊机器人
-
【闲聊机器人】seq2seq模型的原理
随机推荐
- LeetCode 91. 解码方法
- Seq2seq implements chat robot
- [chat robot] principle of seq2seq model
- Leetcode 91. Decoding method
- HCNA Routing&Switching之GVRP
- GVRP of hcna Routing & Switching
- HDU7016 Random Walk 2
- [Code+#1]Yazid 的新生舞会
- CF1548C The Three Little Pigs
- HDU7033 Typing Contest
- HDU7016 Random Walk 2
- [code + 1] Yazid's freshman ball
- CF1548C The Three Little Pigs
- HDU7033 Typing Contest
- Qt Creator 自动补齐变慢的解决
- HALCON 20.11:如何处理标定助手品质问题
- HALCON 20.11:标定助手使用注意事项
- Solution of QT creator's automatic replenishment slowing down
- Halcon 20.11: how to deal with the quality problem of calibration assistant
- Halcon 20.11: precautions for use of calibration assistant
- “十大科学技术问题”揭晓!|青年科学家50²论坛
- "Top ten scientific and technological issues" announced| Young scientists 50 ² forum
- 求反转链表
- Reverse linked list
- js的数据类型
- JS data type
- 记一次文件读写遇到的bug
- Remember the bug encountered in reading and writing a file
- 单例模式
- Singleton mode
- 在这个 N 多编程语言争霸的世界,C++ 究竟还有没有未来?
- In this world of N programming languages, is there a future for C + +?
- es6模板字符
- js Promise
- js 数组方法 回顾
- ES6 template characters
- js Promise
- JS array method review
- 【Golang】️走进 Go 语言️ 第一课 Hello World
- [golang] go into go language lesson 1 Hello World