เมื่อไม่นานมานี้ ฉันได้รับคำขอให้สร้าง Word โดยอัตโนมัติ ตอนนี้ฉันได้รวบรวมขั้นตอนสำคัญบางประการที่จะแบ่งปันแล้ว
แนวคิด: (หมายเหตุ: นี่เป็นสำหรับเวอร์ชัน WORD2003 เท่านั้น ส่วนเวอร์ชันอื่นจะคล้ายกัน)
เนื่องจากข้อมูลภายในและรูปแบบของไฟล์ WORD ถูกจัดเก็บในรูปแบบของไฟล์ XML ไฟล์ WORD จึงสามารถแปลงจากรูปแบบ DOC เป็นรูปแบบ XML ได้อย่างง่ายดาย และสะดวกกว่ามากในการใช้งานไฟล์ XML จึงทำให้สามารถทำงานร่วมกับการดำเนินการที่ไม่ขึ้นกับแพลตฟอร์มต่างๆ ได้ สร้างไฟล์ Word ผ่านการสืบค้นโหนด การแทนที่ การลบ การเพิ่มเติม ฯลฯ ดังนั้น สาระสำคัญของการสร้างไฟล์ WORD ตามเทมเพลตคือกระบวนการแทนที่แท็กพิเศษในไฟล์ XML ด้วยข้อมูลผู้ใช้ จากนั้นจึงบันทึกเป็นไฟล์ DOC
นี่คือขั้นตอนสำคัญบางส่วนที่เกี่ยวข้อง (นำจดหมายแนะนำตัวเป็นตัวอย่าง)
ขั้นตอนที่หนึ่ง: สร้างเทมเพลต WORD ตามความต้องการของคุณ
สร้างไฟล์ WORD ใหม่ในรูปแบบ DOC กรอกเนื้อหาเทมเพลตตามต้องการ และกำหนดรูปแบบของเทมเพลต รวมถึงแบบอักษร สไตล์ บรรทัดว่าง ฯลฯ ใช้แท็กพิเศษ (เช่น: [※Unit Name※]) เพื่อ ครอบครองข้อมูลที่ต้องกรอกล่วงหน้าแล้วบันทึกไฟล์ WORD ที่สร้างขึ้นใหม่เป็นไฟล์รูปแบบ XML ด้วยวิธีนี้ เทมเพลต WORD จึงเสร็จสมบูรณ์ รหัสจะเป็นดังนี้:
เพิ่มไฟล์คอนฟิกูเรชันใหม่ชื่อ template-rule.xml แต่ละโหนดเทมเพลตจะสอดคล้องกับประเภทเทมเพลต มีโหนด taglist ในแต่ละเทมเพลต โหนดย่อยทั้งหมดที่มีอยู่ในโหนดนี้มีข้อมูลเกี่ยวกับโหนดทั้งหมดที่จะถูกแทนที่หรือลบในเทมเพลต ข้อมูลโหนดประกอบด้วย: ค่าโหนด, คุณลักษณะของโหนด ชื่อภาษาอังกฤษ, คำอธิบายภาษาจีน, ประเภทฟิลด์, สามารถลบได้หรือไม่ เป็นต้น เมื่อตั้งค่าไฟล์การกำหนดค่านี้ คุณต้องทราบว่าค่าของแอตทริบิวต์ desc จะต้องสอดคล้องกับตัวยึดตำแหน่งใน XML เทมเพลต ตัวอย่างเช่น: รายการป้อนปี [※ปี※] ที่ตั้งค่าในเทมเพลต XML จะต้องสอดคล้องกับชื่อ desc="Year" ใน template-rule.xml รหัสจะเป็นดังนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
<!--?xml version="1.0" encoding="GB2312"?-->
<!-- คำจำกัดความของเทมเพลต-->
<แม่แบบ>
<!-- คำอธิบาย: S-string; D-amount; M-uppercase amount; ifEmptyDelete: T-value ว่างเปล่าเพื่อลบโหนดหลัก ค่าเริ่มต้นคือ F -->
<template name="RECOMMEND-LETTER" desc="จดหมายแนะนำตัว" templatefile="template4.xml">
<taglist remark="รายการแท็กค่าเดียว">
<tag id="1" name="ToPartment" desc="แผนกรับ" type="S" ifemptydelete="T">#ToPartment</tag><!--แผนกรับ-->
<tag id="2" name="OwnerName" desc="Name" type="S">#OwnerName</tag><!--ชื่อ-->
<tag id="3" name="CountNum" desc="จำนวนคน" type="S">#CountNum</tag><!--จำนวนคน-->
<tag id="4" name="ธุรกิจ" desc="Content" type="S">#ธุรกิจ</tag><!--เนื้อหา-->
<tag id="5" name="UsefulDays" desc="ระยะเวลาที่ใช้ได้" type="S">#UsefulDays</tag><!--ระยะเวลาที่ใช้ได้-->
<tag id="6" name="ปี" desc="ปี" type="S">#ปี</tag><!--ปี-->
<tag id="7" name="เดือน" desc="เดือน" type="S">#เดือน</tag><!--เดือน-->
<tag id="8" name="Day" desc="日" type="S">#วัน</tag><!--วัน-->
</แท็กรายการ>
</แม่แบบ>
</แม่แบบ>
ขั้นตอนที่ 3: เขียนโค้ดจาวา
คัดลอกรหัสรหัสดังต่อไปนี้:
-
* พารามิเตอร์และกฎ
-
RuleDTO ระดับสาธารณะ {
-
* ชื่อแท็ก
-
parmName สตริงส่วนตัว;
-
* คำอธิบายแท็ก
-
parmDesc สตริงส่วนตัว;
-
* แท็กหมายเลขซีเรียล
-
สตริงส่วนตัว parmSeq;
-
* ประเภทค่าแท็ก
-
parmType สตริงส่วนตัว;
-
* ชื่อพารามิเตอร์แท็ก
-
สตริงส่วนตัว parmRegular;
-
* ค่าแท็ก
-
สตริง parmValue ส่วนตัว;
-
* หากค่าแท็กว่างเปล่า ให้ลบแอตทริบิวต์นี้
-
สตริงส่วนตัว ifEmptyDelete;
-
คัดลอกรหัสรหัสดังต่อไปนี้:
-
* คำอธิบาย: ข้อมูลเทมเพลต Word
-
เทมเพลตชั้นเรียนสาธารณะ {
ชื่อสตริงส่วนตัว;//ชื่อเทมเพลต
สตริงส่วนตัว desc;//คำอธิบายเทมเพลต
สตริงส่วนตัว templateFile;//ไฟล์เทมเพลต
กฎเวกเตอร์ <ruledto> ส่วนตัว;//กฎเทมเพลต
</ruledto>
คัดลอกรหัสรหัสดังต่อไปนี้:
WordBuilder คลาสสาธารณะ {
-
* อ่านกฎการแทนที่ตามเทมเพลต
* @param templateName รหัสเทมเพลต
-
@SuppressWarnings("ไม่ได้เลือก")
เทมเพลตสาธารณะ loadRules (แผนที่ <string, string=""> lawValue) {
อินพุตสตรีมใน = null;
เทมเพลต เทมเพลต = เทมเพลตใหม่();
// เส้นทางไฟล์การกำหนดค่ากฎ
สตริงกฎไฟล์ = "template-rule.xml";
// ชื่อกฎเทมเพลต
สตริง templateRuleName = "";
พยายาม {
templateRuleName = lawValue.get("ruleName");
//อ่านไฟล์กฎเทมเพลต
ใน = this.getClass().getClassLoader().getResourceAsStream(ruleFile);
// แยกกฎเทมเพลต
SAXBuilder sb = ใหม่ SAXBuilder();
เอกสาร doc = sb.build(ใน);
องค์ประกอบ root = doc.getRootElement(); // รับองค์ประกอบราก
รายการ<องค์ประกอบ> templateList = root.getChildren();//การกำหนดค่าเทมเพลตทั้งหมด
องค์ประกอบองค์ประกอบ = โมฆะ;
กฎเวกเตอร์<ruledto> = null;
for (int i = 0; i < templateList.size(); i++) {// สำรวจเทมเพลตทั้งหมด
องค์ประกอบ = (องค์ประกอบ) templateList.get(i);
สตริง templateName = element.getAttributeValue("ชื่อ");
ถ้า (templateRuleName.equalsIgnoreCase(templateName)) {//ค้นหาการกำหนดค่าเทมเพลตที่กำหนด
template.setName(ชื่อเทมเพลต);
template.setDesc(element.getAttributeValue("คำอธิบาย"));
template.setTemplateFile(องค์ประกอบ
.getAttributeValue("templateFile"));
รายการ<องค์ประกอบ> tagList = ((องค์ประกอบ) element.getChildren()
.get(0)).getChildren(); // รายการแท็ก
แท็กองค์ประกอบ = null;
RuleDTO กฎ DTO = null;
กฎ = เวกเตอร์ใหม่<ruledto>();
สำหรับ (int j = 0; j < tagList.size(); j++) {
tag = (องค์ประกอบ) tagList.get(j);
กฎ DTO = กฎ DTO ใหม่ ();
RuleDTO.setParmName(tag.getAttributeValue("ชื่อ"));
กฎDTO.setParmDesc("【※'
+ tag.getAttributeValue("คำอธิบาย") + "※】");
กฎDTO.setParmSeq(tag.getAttributeValue("id"));
RuleDTO.setParmType(tag.getAttributeValue("ประเภท"));
ถ้า ("T".equalsIgnoreCase(tag
.getAttributeValue("ifEmptyDelete"))) {// สามารถลบเครื่องหมายได้หรือไม่
กฎDTO.setIfEmptyDelete("T");
} อื่น {
กฎDTO.setIfEmptyDelete("F");
-
กฎDTO.setParmRegular(tag.getText());
// ค่า
// กำหนดประเภทพารามิเตอร์
ค่าสตริง = (สตริง) ((แมป<สตริง, สตริง="">) ค่ากฎ)
.get(ruleDTO.getParmRegular().replaceAll("#",
-
กฎDTO.setParmValue (ค่า);
กฎ.เพิ่ม(ruleDTO);
-
template.setRules(กฎ);
หยุดพัก;
-
-
} จับ (FileNotFoundException จ) {
e.printStackTrace();
} จับ (JDOMException จ) {
e.printStackTrace();
} จับ (IOException จ) {
e.printStackTrace();
} ในที่สุด {
พยายาม {
ใน.ปิด();
} จับ (ข้อยกเว้นจ) {
e.printStackTrace();
-
-
แม่แบบการส่งคืน;
-
-
* ค้นหาโหนดหลัก
-
องค์ประกอบสาธารณะ findElement (องค์ประกอบ currNode, สตริง parentNodeId) {
//โหนดถูกทำเครื่องหมายว่าว่างเปล่า
ถ้า (currNode == null || parentNodeId == null) {
กลับเป็นโมฆะ;
-
องค์ประกอบ pNode = โมฆะ;
ทำ {
pNode = currNode.getParent();
currNode = pNode;
} ในขณะที่ (parentNodeId.equalsIgnoreCase(pNode.getName()));
กลับ pNode;
-
-
* สร้างไฟล์ Word
-
@SuppressWarnings("ไม่ได้เลือก")
การสร้างสตริงสาธารณะ (เทมเพลตเทมเพลต) {
อินพุตสตรีมใน = null;
OutputStream สำหรับ = null;
//เส้นทางไปยังไฟล์ที่สร้างขึ้น
ไฟล์สตริง = "d://test//" + template.getDesc() + ".doc";
พยายาม {
//อ่านไฟล์เทมเพลต
ใน = this.getClass().getClassLoader()
.getResourceAsStream(template.getTemplateFile());
SAXBuilder sb = SAXBuilder ใหม่ ();
เอกสาร doc = sb.build(in);
องค์ประกอบ root = doc.getRootElement(); // รับองค์ประกอบราก
เนมสเปซ ns = root.getNamespace();// เนมสเปซ
// มีองค์ประกอบ <wx:sect> ในเทมเพลต word 03
รายการ<องค์ประกอบ> sectList = root.getChild("body", ns).getChildren();
องค์ประกอบ sectElement = (องค์ประกอบ) sectList.get(0);
// การรวบรวมแท็กภายใต้ <w:p>
รายการ<องค์ประกอบ> pTagList = sectElement.getChildren("p", ns);
// ชุดของแท็กภายใต้ <w:tbl>
รายการ <องค์ประกอบ> tblTagList = sectElement.getChildren("tbl", ns);
ถ้า (pTagList != null && pTagList.size() > 0) {
changeValue4PTag(pTagList, template.getRules(), ns, null);
-
ถ้า (tblTagList != null && tblTagList.size() > 0) {
changeValue4TblTag(tblTagList, template.getRules(), ns);
-
//เขียนไฟล์
XMLOutputter outp = ใหม่ XMLOutputter(" ", จริง, "UTF-8");
fo = FileOutputStream ใหม่ (ไฟล์);
outp.output(doc, สำหรับ);
} จับ (FileNotFoundException จ) {
e.printStackTrace();
} จับ (JDOMException จ) {
e.printStackTrace();
} จับ (IOException จ) {
e.printStackTrace();
} ในที่สุด {
พยายาม {
ใน.ปิด();
fo.ปิด();
} จับ (ข้อยกเว้นจ) {
e.printStackTrace();
-
-
ไฟล์ส่งคืน;
-
-
* สำหรับเทมเพลต WORD ระดับ <w:body><wx:sect><w:p> ให้ค้นหาและแทนที่แท็กภายใต้ <w:p>
* @param pTagList:<w:p>คอลเลกชัน
* @param RuleValue: คอลเลกชัน RuleDTO
* @param ns: วัตถุ NameSpace
* @param trChildren: การรวบรวมโหนดย่อย <w:tr> จาก <w:tbl>
-
@SuppressWarnings("ไม่ได้เลือก")
changeValue4PTag ส่วนตัวบูลีน (รายการ <องค์ประกอบ> pTagList,
เวกเตอร์ <ruledto> กฎค่า, เนมสเปซ ns, รายการ <องค์ประกอบ> trChildren) {
องค์ประกอบ p = โมฆะ;
บูลีน delFlag = เท็จ;
สำหรับ (int i = 0; i < pTagList.size(); i++) {
boolean delCurrNode = false;//ลบโหนดปัจจุบัน
boolean delCurrNode4TabWR = false;//ลบโหนดแถวเดียวในตาราง
p = (องค์ประกอบ) pTagList.get(i);
รายการ <องค์ประกอบ> pChild = p.getChildren("r", ns);
สำหรับ (int j = 0; pChild != null && j < pChild.size(); j++) {
องค์ประกอบ pChildren = (องค์ประกอบ) pChild.get(j);
องค์ประกอบ t = pChildren.getChild("t", ns);
ถ้า (t != null) {
ข้อความสตริง = t.getTextTrim();
ถ้า (text.indexOf("【※") != -1) {
สำหรับ (int v = 0; v < RuleValue.size(); v++) {
RuleDTO dto = (RuleDTO) กฎValue.get(v);
ถ้า (text.indexOf(dto.getParmDesc().trim()) != -1) {
// ตรวจสอบว่าค่าแอตทริบิวต์เป็นโมฆะสำหรับการลบหรือไม่
ถ้า ("T".เท่ากับ(dto.getIfEmptyDelete())
&& StringUtils.isBlank(dto
.getParmValue())) {
//ลบโหนดบนสุดของโหนดนี้
ข้อความ = "";
if (trChildren != null) {//ลบแถวนี้สำหรับ <w:tbl>
องค์ประกอบ องค์ประกอบ = ((องค์ประกอบ) หน้า
.getParent()).getParent();
trChildren.remove(องค์ประกอบ);
delCurrNode4TabWR = จริง;
} else {//ลบส่วนของ <w:r>
// pTagList.remove(p);
pTagList.remove(pChildren);
delCurrNode = จริง;
-
หยุดพัก;
} อื่น {
ข้อความ = text.replaceAll(dto.getParmDesc()
.trim(), dto.getParmValue());
-
-
-
t.setText(ข้อความ);
-
ถ้า (delCurrNode4TabWR) {// <w:tbl>โหนดแถวใต้ TABLE ถูกลบแล้ว
เดลแฟลก = จริง;
หยุดพัก;
} อื่นถ้า (delCurrNode) {// โหนดภายใต้ <w:p> ถูกลบแล้ว
ฉัน--;
เดลแฟลก = จริง;
หยุดพัก;
-
-
-
-
กลับ delFlag;
-
-
* สำหรับเทมเพลต WORD ที่มีตาราง ให้ค้นหาและแทนที่แท็กภายใต้ <w:tbl>
* @param tblTagList:<w:tbl> คอลเลกชัน
* @param RuleValue: คอลเลกชัน RuleDTO
* @param ns: วัตถุ NameSpace
-
@SuppressWarnings("ไม่ได้เลือก")
โมฆะส่วนตัว changeValue4TblTag (รายการ <องค์ประกอบ> tblTagList,
เวกเตอร์ <ruledto> กฎค่า เนมสเปซ ns) {
องค์ประกอบ p = โมฆะ;
สำหรับ (int i = 0; tblTagList != null && i < tblTagList.size(); i++) {
p = (องค์ประกอบ) tblTagList.get(i);
รายการ <องค์ประกอบ> trChildren = p.getChildren("tr", ns);
สำหรับ (int j = 0; trChildren != null && j < trChildren.size(); j++) {// วนซ้ำ<w:tr>
องค์ประกอบ pChildren = (องค์ประกอบ) trChildren.get(j);
รายการ <องค์ประกอบ> tcTagList = pChildren.getChildren("tc", ns);
for (int c = 0; tcTagList != null && c < tcTagList.size(); c++) {// Loop <w:tc> เพื่อรับคอลเล็กชัน <w:p>
องค์ประกอบ tcChildren = (องค์ประกอบ) tcTagList.get(c);
รายการ<องค์ประกอบ> pTagList = tcChildren.getChildren("p", ns);
บูลีน delFlag = changeValue4PTag (pTagList, กฎค่า,
ns, trChildren);
if (delFlag) {// หลังจากลบแถวแล้ว คุณต้องเปลี่ยนตำแหน่งตัวชี้ของ trChildren
เจ--;
-
-
-
-
-
โมฆะคงที่สาธารณะ main (String [] args) พ่นข้อยกเว้น {
WordBuilder = WordBuilder ใหม่ ();
แผนที่<string, string=""> แผนที่ = ใหม่ HashMap<string, string="">();
//กรอกพารามิเตอร์
map.put("ToPartment", "XXX บริษัท");
map.put("OwnerName", "Zhang San");
map.put("CountNum", "5");
map.put("ธุรกิจ", "การตรวจสอบตามปกติ");
map.put("วันที่มีประโยชน์", "15");
map.put("ปี", "2014");
map.put("เดือน", "5");
map.put("วัน", "13");
map.put("ruleName", "RECOMMEND-LETTER");
เทมเพลตเทมเพลต = word.loadRules (แผนที่);
//เปิดไฟล์โดยตรง
Runtime.getRuntime().exec("explorer " + word.build(เทมเพลต));
-
</string,></string,></element></w:p></w:tc></element></w:tr></element></ruledto></element>< /w:tbl></w:tbl></w:p></w:tbl></w:r></w:tbl></element></element></ruledto></ele ment></w:tr></w:tbl></w:p></w:p></w:p></wx:sect></w:body></element></ w:tbl></element></w:p></element></wx:sect></string,></ruledto></element></ruledto></element></string,>
ขั้นตอนที่ 4: เสร็จสิ้น
ประเด็นและหมายเหตุสรุปบางส่วน:
1. ชื่อองค์ประกอบที่กำหนดจะต้องสอดคล้องกับค่าที่สอดคล้องกับชื่อเดียวกันใน template_rule.xml ไม่เช่นนั้นจะต้องตั้งค่ากฎการแปลง
2. ข้อความในตัวยึดตำแหน่ง [※※] ที่กำหนดในเทมเพลต xml จะต้องเหมือนกับข้อความรายละเอียดที่เกี่ยวข้องใน template_rule.xml ไม่เช่นนั้นจะต้องตั้งค่ากฎการแปลง
3. หลังจากกำหนดค่าเทมเพลต XML แล้ว คุณต้องตรวจสอบว่าโหนดย่อยภายใต้ป้ายกำกับนั้นเป็นป้ายกำกับหรือไม่ (เกี่ยวข้องกับเวอร์ชัน WORD) หากไม่ใช่ จะต้องเพิ่มป้ายกำกับ
4. หากคุณต้องการลบโหนดป้ายกำกับแบบไดนามิก เนื้อหาของโหนดนี้จะต้องอยู่ในบรรทัดเดียวกันในเทมเพลต หากไม่เป็นเช่นนั้น คุณสามารถปรับเทมเพลต XML ได้ด้วยตนเอง
5. หากคุณต้องการใช้ฟังก์ชันการตัดบรรทัดอัตโนมัติของ WORD (ยังไม่มีวิธีแก้ปัญหาที่ดีกว่าสำหรับการตัดบรรทัดในเทมเพลต) คุณต้องคำนวณจำนวนคำในบรรทัดที่เกี่ยวข้องของเทมเพลตก่อน จากนั้นจึงใช้การเติมช่องว่าง เพื่อให้บรรลุเป้าหมาย