首页 > 代码库 > Web应用Word生成

Web应用Word生成

    前段时间接到一个Web应用自动生成Word的需求,现整理了下一些关键步骤拿来分享一下。

 

思路:(注:这里只针对WORD2003版本,其它版本大同小异。)

因为WORD文件内部的数据及格式等是通过XML文件的形式存储的,所以WORD文件可以很方便的实现由DOC到XML格式的相互转换,而操作XML文件就方便的多了,这样就实现了与平台无关的各种操作,通过节点的查询、替换、删除、新增等生成Word文件。所以,根据模板生成WORD文件实质就是由用户数据替换XML文件中特殊标签,然后另存为一个DOC文件的过程。

 

下面列举涉及到的一些关键步骤(以介绍信为例)

第一步:根据需求制作WORD模板

新建一个DOC格式的WORD文件,根据需要填写好模板内容,设置好模板的格式,包括字体,样式,空行等等,需要填充的数据使用特殊标签(如:【※单位名称※】)预先占位,然后将新建的WORD文件另存为XML格式文件。这样, WORD模板就制作完成了,代码如下:

 template4.xml
 

第二步:在配置文件中配置好模板信息

新增名为template-rule.xml的配置文件,每个template节点对应一个模板类型。每个template中有一个taglist节点,该节点包含的所有子节点包含了模板所有将要替换、删除节点信息,节点信息包括:节点值,节点属性英文名称,中文描述,字段类型,可否删除等信息。在设置这个配置文件时候,需要注意desc属性的值必须与模板XML中的占位符一致。比如:模板XML中设置的年份这个录入项【※年※】需与template-rule.xml中的desc=""名称对应,代码如下:

  

<?xml version="1.0" encoding="GB2312"?><!-- 模板定义 --><templates>	<!-- 说明: S-字符串; D-日期; E-金额; M-大写金额; ifEmptyDelete: T-值为空删除父节点,默认为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="姓名" type="S">#OwnerName</tag><!--姓名-->			<tag id="3" name="CountNum" desc="人数" type="S">#CountNum</tag><!--人数-->			<tag id="4" name="Business" desc="内容" type="S">#Business</tag><!--内容-->			<tag id="5" name="UsefulDays" desc="有效期" type="S">#UsefulDays</tag><!--有效期-->			<tag id="6" name="Year" desc="年" type="S">#Year</tag><!--年-->			<tag id="7" name="Month" desc="月" type="S">#Month</tag><!--月-->			<tag id="8" name="Day" desc="日" type="S">#Day</tag><!--日-->		</taglist>	</template></templates>

 

第三步:编写java代码

/** * 参数及规则 */public class RuleDTO {	/**	 * tag名称	 */	private String parmName;	/**	 * tag描述	 */	private String parmDesc;	/**	 * tag序号	 */	private String parmSeq;	/**	 * tag值类型	 */	private String parmType;	/**	 * tag参数名称	 */	private String parmRegular;	/**	 * tag值	 */	private String parmValue;		/**	 * tag值为空删除该属性	 */	private String ifEmptyDelete;}
/** * 描述: Word模板信息 */public class Template {	private String name;//模板名		private String desc;//模板描述		private String templateFile;//模板文件		private Vector<RuleDTO> rules;//模板规则		}


public class WordBuilder {	/**	 * 根据模板读取替换规则	 * @param templateName  模板ID	 */	@SuppressWarnings("unchecked")	public Template loadRules(Map<String, String> ruleValue) {		InputStream in = null;		Template template = new Template();		// 规则配置文件路径		String ruleFile = "template-rule.xml";		// 模板规则名称		String templateRuleName = "";		try {			templateRuleName = ruleValue.get("ruleName");			// 读取模板规则文件			in = this.getClass().getClassLoader().getResourceAsStream(ruleFile);			// 解析模板规则			SAXBuilder sb = new SAXBuilder();			Document doc = sb.build(in);			Element root = doc.getRootElement(); // 得到根元素			List<Element> templateList = root.getChildren();// 所有模板配置			Element element = null;			Vector<RuleDTO> rules = null;			for (int i = 0; i < templateList.size(); i++) {// 遍历所有模板				element = (Element) templateList.get(i);				String templateName = element.getAttributeValue("name");				if (templateRuleName.equalsIgnoreCase(templateName)) {// 查找给定的模板配置					template.setName(templateName);					template.setDesc(element.getAttributeValue("desc"));					template.setTemplateFile(element							.getAttributeValue("templateFile"));					List<Element> tagList = ((Element) element.getChildren()							.get(0)).getChildren();// tag列表					Element tag = null;					RuleDTO ruleDTO = null;					rules = new Vector<RuleDTO>();					for (int j = 0; j < tagList.size(); j++) {						tag = (Element) 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"));						if ("T".equalsIgnoreCase(tag								.getAttributeValue("ifEmptyDelete"))) {// 是否可删除标记							ruleDTO.setIfEmptyDelete("T");						} else {							ruleDTO.setIfEmptyDelete("F");						}						ruleDTO.setParmRegular(tag.getText());						// 值						// 判断参数类型						String value = http://www.mamicode.com/(String) ((Map) ruleValue)>

 

 第四步:大功告成

 

几点总结及注意事项:

1.  定义的元素name必须与template_rule.xml中对应相同的name的值一致,否则需要设置转换规则。

2.  模板xml中定义的占位符【※※】中的文字必须与template_rule.xml中对应的desc相同,否则需要设置转换规则.

3.  在配置好模板XML后,需要检查<w:body>标签下的子节点是否是<wx:sect>标签(与WORD版本有关),如果没有,则必须加上该标签。

4.  如果要动态删除<w:p>标签节点,则这个节点的内容需要在模板中的同一行,如果不是,则可以手动调整模板XML

5.  如果需要实现WORD自动换行功能(关于模板中换行的方案暂没有想到更好的),则需要首先计算出对应模板该行的字数,然后采用空格填充来实现。