منذ بعض الوقت، تلقيت طلبًا لتطبيق ويب لإنشاء Word تلقائيًا. والآن قمت بتجميع بعض الخطوات الأساسية لمشاركتها.
الفكرة: (ملاحظة: هذا مخصص لإصدار WORD2003 فقط، والإصدارات الأخرى مشابهة.)
نظرًا لأنه يتم تخزين البيانات الداخلية وتنسيق ملفات WORD في شكل ملفات XML، يمكن تحويل ملفات WORD بسهولة من تنسيق DOC إلى تنسيق XML، ويكون تشغيل ملفات XML أكثر ملاءمة، وبالتالي تحقيق التكامل مع العمليات المختلفة المستقلة عن النظام الأساسي إنشاء ملفات Word من خلال استعلام العقدة، والاستبدال، والحذف، والإضافة، وما إلى ذلك. لذلك، فإن جوهر إنشاء ملف WORD استنادًا إلى القالب هو عملية استبدال العلامات الخاصة في ملف XML ببيانات المستخدم ثم حفظها كملف DOC.
فيما يلي بعض الخطوات الأساسية المتبعة (مع أخذ خطاب المقدمة كمثال)
الخطوة الأولى: قم بإنشاء قالب WORD وفقًا لاحتياجاتك
قم بإنشاء ملف WORD جديد بتنسيق DOC، واملأ محتوى القالب حسب الحاجة، وقم بتعيين تنسيق القالب، بما في ذلك الخطوط والأنماط والأسطر الفارغة وما إلى ذلك. استخدم علامات خاصة (مثل: [※اسم الوحدة※]) لـ قم بشغل البيانات التي تحتاج إلى تعبئتها مسبقًا، ثم قم بحفظ ملف WORD الذي تم إنشاؤه حديثًا كملف بتنسيق XML. بهذه الطريقة، يتم إكمال قالب WORD، ويكون الكود كما يلي:
قم بإضافة ملف تكوين جديد باسم template-rule.xml، كل عقدة قالب تتوافق مع نوع القالب. توجد عقدة قائمة علامات في كل قالب. تحتوي جميع العقد الفرعية الموجودة في هذه العقدة على معلومات حول جميع العقد التي سيتم استبدالها أو حذفها في القالب. تتضمن معلومات العقدة: قيمة العقدة، والاسم الإنجليزي لسمة العقدة، والوصف الصيني، ونوع الحقل، ما إذا كان يمكن حذفه، وما إلى ذلك. عند تعيين ملف التكوين هذا، عليك ملاحظة أن قيمة السمة desc يجب أن تكون متسقة مع العنصر النائب في قالب XML. على سبيل المثال: يجب أن يتوافق عنصر إدخال السنة [※Year※] الذي تم تعيينه في قالب XML مع اسم desc="Year" في template-rule.xml، ويكون الرمز كما يلي:
انسخ رمز الكود كما يلي:
<!--?xml version="1.0" encoding="GB2312"?-->
<!--تعريف القالب-->
<قوالب>
<!-- الوصف: S-string; E-amount;
<template name="RECOMMEND-LETTER" desc="خطاب المقدمة" templatefile="template4.xml">
<taglistmark="قائمة علامات القيمة المفردة">
<tag id="1" name="ToPartment" desc="قسم الاستلام" type="S" ifemptydelete="T">#ToPartment</tag><!--قسم الاستلام-->
<tag id="2" name="OwnerName" desc="Name" type="S">#OwnerName</tag><!--Name-->
<tag id="3" name="CountNum" desc="عدد الأشخاص" type="S">#CountNum</tag><!--عدد الأشخاص-->
<tag id="4" name="Business" desc="Content" type="S">#Business</tag><!--Content-->
<tag id="5" name="UsefulDays" desc="فترة الصلاحية" type="S">#UsefulDays</tag><!--فترة الصلاحية-->
<tag id="6" name="Year" desc="year" type="S">#Year</tag><!--year-->
<tag id="7" name="Month" desc="month" type="S">#شهر</tag><!--month-->
<tag id="8" name="Day" desc="日" type="S">#Day</tag><!--Day-->
</taglist>
</قالب>
</القوالب>
الخطوة 3: كتابة كود جافا
انسخ رمز الكود كما يلي:
/**
* المعلمات والقواعد
*/
قاعدة الطبقة العامة {
/**
* اسم العلامة
*/
سلسلة خاصة parmName؛
/**
* وصف العلامة
*/
سلسلة خاصة parmDesc؛
/**
* علامة الرقم التسلسلي
*/
سلسلة خاصة parmSeq؛
/**
* نوع قيمة العلامة
*/
سلسلة خاصة parmType؛
/**
* اسم معلمة العلامة
*/
سلسلة خاصة parmRegular؛
/**
* قيمة العلامة
*/
سلسلة خاصة parmValue؛
/**
* إذا كانت قيمة العلامة فارغة، فاحذف هذه السمة
*/
سلسلة خاصة ifEmptyDelete؛
}
انسخ رمز الكود كما يلي:
/**
* الوصف: معلومات قالب Word
*/
قالب الطبقة العامة {
اسم السلسلة الخاصة؛ // اسم القالب
وصف سلسلة خاصة؛//وصف القالب
ملف سلسلة خاص؛ // ملف القالب
قواعد المتجهات الخاصة <ruledto>؛ // قواعد القالب
</ruledto>
انسخ رمز الكود كما يلي:
الطبقة العامة WordBuilder {
/**
* قراءة قواعد الاستبدال بناءً على القالب
* @param templateName معرف القالب
*/
@SuppressWarnings("تم إلغاء التحديد")
تحميل القالب العام (Map<string, string=""> RuleValue) {
InputStream in = null;
قالب القالب = قالب جديد ()؛
// مسار ملف تكوين القاعدة
String RuleFile = "template-rule.xml";
// اسم قاعدة القالب
String templateRuleName = "";
يحاول {
templateRuleName = RuleValue.get("ruleName");
// قراءة ملف قاعدة القالب
in = this.getClass().getClassLoader().getResourceAsStream(ruleFile);
// تحليل قواعد القالب
SAXBuilder sb = new SAXBuilder();
المستند doc = sb.build(in);
جذر العنصر = doc.getRootElement(); // احصل على العنصر الجذر
List<element> templateList = root.getChildren();//جميع تكوينات القالب
عنصر العنصر = فارغ؛
قواعد المتجهات <ruledto> = فارغة؛
for (int i = 0; i < templateList.size(); i++) {// اجتياز جميع القوالب
العنصر = (العنصر) templateList.get(i);
String templateName = element.getAttributeValue("name");
إذا (templateRuleName.equalsIgnoreCase(templateName)) {// ابحث عن تكوين القالب المحدد
template.setName(templateName);
template.setDesc(element.getAttributeValue("desc"));
template.setTemplateFile(element
.getAttributeValue("templateFile"));
قائمة <element> tagList = ((Element) element.getChildren()
.get(0)).getChildren(); // قائمة العلامات
علامة العنصر = فارغة؛
RuleDTO RuleDTO = null;
القواعد = ناقل جديد<ruledto>();
لـ (int j = 0; j < tagList.size(); j++) {
العلامة = (العنصر) tagList.get(j);
RuleDTO = new RuleDTO();
RuleDTO.setParmName(tag.getAttributeValue("name"));
RuleDTO.setParmDesc("【※"
+ tag.getAttributeValue("desc") + "※】");
RuleDTO.setParmSeq(tag.getAttributeValue("id"));
RuleDTO.setParmType(tag.getAttributeValue("type"));
إذا ("T".equalsIgnoreCase(tag
.getAttributeValue("ifEmptyDelete"))) {// ما إذا كان من الممكن حذف العلامة
RuleDTO.setIfEmptyDelete("T");
} آخر {
RuleDTO.setIfEmptyDelete("F");
}
RuleDTO.setParmRegular(tag.getText());
// قيمة
// تحديد نوع المعلمة
قيمة السلسلة = (سلسلة) ((Map<string, string="">) RuleValue)
.get(ruleDTO.getParmRegular().replaceAll("#"،
""));
RuleDTO.setParmValue(value);
Rules.add(ruleDTO);
}
template.setRules(rules);
استراحة؛
}
}
} قبض على (FileNotFoundException ه) {
printStackTrace();
} مسك (JDOMException e) {
printStackTrace();
} قبض (IOException ه) {
printStackTrace();
} أخيراً {
يحاول {
in. Close();
} قبض (الاستثناء ه) {
printStackTrace();
}
}
قالب الإرجاع؛
}
/**
* ابحث عن العقدة الأم
*/
العنصر العام findElement(Element currNode, StringparentNodeId) {
// تم وضع علامة على العقدة على أنها فارغة
إذا (currNode == null ||parentNodeId == null) {
عودة فارغة؛
}
العنصر pNode = null;
يفعل {
pNode = currNode.getParent();
currNode = pNode;
} while (parentNodeId.equalsIgnoreCase(pNode.getName()));
إرجاع العقدة؛
}
/**
* توليد ملف وورد
*/
@SuppressWarnings("تم إلغاء التحديد")
بناء السلسلة العامة (قالب القالب) {
InputStream in = null;
OutputStream fo = null;
// المسار إلى الملف الذي تم إنشاؤه
ملف السلسلة = "d://test//" + template.getDesc() + ".doc"؛
يحاول {
// قراءة ملف القالب
في = this.getClass().getClassLoader()
.getResourceAsStream(template.getTemplateFile());
SAXBuilder sb = new SAXBuilder();
المستند doc = sb.build(in);
جذر العنصر = doc.getRootElement(); // احصل على العنصر الجذر
مساحة الاسم ns = root.getNamespace();// NameSpace
// العنصر <wx:sect> موجود في قالب الكلمة 03
List<element> sectList = root.getChild("body", ns).getChildren();
العنصر sectElement = (Element) sectList.get(0);
// مجموعة من العلامات ضمن <w:p>
List<element> pTagList = sectElement.getChildren("p", ns);
// مجموعة العلامات ضمن <w:tbl>
List<element> 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 = new XMLOutputter(" ", true, "UTF-8");
fo = new FileOutputStream(file);
outp.output(doc, fo);
} قبض على (FileNotFoundException ه) {
printStackTrace();
} مسك (JDOMException e) {
printStackTrace();
} قبض (IOException ه) {
printStackTrace();
} أخيراً {
يحاول {
in. Close();
fo.Close();
} قبض (الاستثناء ه) {
printStackTrace();
}
}
ملف الإرجاع؛
}
/**
* بالنسبة لقوالب WORD من المستوى <w:body><wx:sect><w:p>، ابحث عن العلامات واستبدلها ضمن <w:p>.
*param pTagList:<w:p>مجموعة
*param RulesValue: مجموعة RuleDTO
*param ns: كائن NameSpace
* @param trChildren: مجموعة العقد الفرعية <w:tr> من <w:tbl>
*/
@SuppressWarnings("تم إلغاء التحديد")
تغيير منطقي خاصValue4PTag(List<element> pTagList,
المتجهات<ruledto> القواعدValue، Namespace ns، List<element> trChildren) {
العنصر ع = فارغ؛
boolean delFlag = false;
for (int i = 0; i < pTagList.size(); i++) {
boolean delCurrNode = false;// احذف العقدة الحالية
boolean delCurrNode4TabWR = false;// حذف عقدة صف واحد في الجدول
ع = (العنصر) pTagList.get(i);
List<element> pChild = p.getChildren("r"، ns);
for (int j = 0; pChild != null && j < pChild.size(); j++) {
العنصر pChildren = (العنصر) pChild.get(j);
العنصر t = pChildren.getChild("t"، ns);
إذا (ر!= فارغة) {
نص السلسلة = t.getTextTrim();
إذا (text.indexOf("【※") != -1) {
for (int v = 0; v < القواعدValue.size(); v++) {
RuleDTO dto = (RuleDTO) القواعدValue.get(v);
إذا (text.indexOf(dto.getParmDesc().trim()) != -1) {
// تحديد ما إذا كانت قيمة السمة فارغة للحذف
إذا ("T". يساوي (dto.getIfEmptyDelete())
&& StringUtils.isBlank(dto
.getParmValue())) {
// احذف العقدة العلوية لهذه العقدة
نص = "";
إذا (trChildren != null) {// احذف هذا الصف لـ <w:tbl>
عنصر العنصر = ((عنصر) ص
.getParent()).getParent();
trChildren.remove(element);
delCurrNode4TabWR = true;
} else {// احذف المقطع لـ <w:r>
// pTagList.remove(p);
pTagList.remove(pChildren);
delCurrNode = true;
}
استراحة؛
} آخر {
النص = text.replaceAll(dto.getParmDesc())
.trim(), dto.getParmValue());
}
}
}
t.setText(text);
}
إذا (delCurrNode4TabWR) {// <w:tbl>تم حذف عقدة الصف الموجودة ضمن TABLE
delFlag = true;
استراحة؛
} else if (delCurrNode) {// تم حذف العقدة الموجودة تحت <w:p>
أنا--؛
delFlag = true;
استراحة؛
}
}
}
}
إرجاع ديل فلاج؛
}
/**
* بالنسبة لقوالب WORD التي تحتوي على جداول، ابحث عن العلامات واستبدلها ضمن <w:tbl>.
* @param tblTagList: مجموعة <w:tbl>
*param RulesValue: مجموعة RuleDTO
*param ns: كائن NameSpace
*/
@SuppressWarnings("تم إلغاء التحديد")
تغيير الفراغ الخاصValue4TblTag(List<element> tblTagList,
ناقل <ruledto> القواعد، القيمة، مساحة الاسم ns) {
العنصر ع = فارغ؛
for (int i = 0; tblTagList != null && i < tblTagList.size(); i++) {
ع = (العنصر) tblTagList.get(i);
List<element> trChildren = p.getChildren("tr"، ns);
for (int j = 0; trChildren != null && j < trChildren.size(); j++) {// حلقة<w:tr>
العنصر pChildren = (Element) trChildren.get(j);
List<element> tcTagList = pChildren.getChildren("tc", ns);
for (int c = 0; tcTagList != null && c < tcTagList.size(); c++) {// قم بتكرار <w:tc> للحصول على مجموعة <w:p>
العنصر tcChildren = (العنصر) tcTagList.get(c);
List<element> pTagList = tcChildren.getChildren("p", ns);
boolean delFlag = ChangeValue4PTag(pTagList, RulesValue,
ns، trChildren)؛
إذا (delFlag) {// بعد حذف الصف، تحتاج إلى تغيير موضع مؤشر trChildren
ي--؛
}
}
}
}
}
public static void main(String[] args) يطرح الاستثناء {
WordBuilder word = new WordBuilder();
Map<string, string=""> Map = new HashMap<string, string="">();
// ملء المعلمات
Map.put("ToPartment"، "XXX Company");
Map.put("اسم المالك", "تشانغ سان");
Map.put("CountNum", "5");
Map.put("الأعمال"، "الفحص الروتيني");
Map.put("UsefulDays", "15");
Map.put("السنة"، "2014");
Map.put("الشهر", "5");
Map.put("اليوم", "13");
Map.put("ruleName", "RECOMMEND-LETTER");
قالب القالب = word.loadRules(map);
// افتح الملف مباشرة
Runtime.getRuntime().exec("explorer" + word.build(template));
}
</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 منت></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 (لا يوجد حل أفضل لالتفاف الأسطر في القوالب حتى الآن)، فأنت بحاجة أولاً إلى حساب عدد الكلمات في السطر المقابل من القالب، ثم استخدام ملء المسافة لتحقيق ذلك.