A small JAVA project Web application automatically generates Word

  • 2020-04-01 03:23:05
  • OfStack

Some time ago, I received a request from a Web application to automatically generate Word. Now I have compiled the following key steps to share with you.

Idea: note: this is for WORD2003 only, other versions are similar.

Because WORD and data within the file format is through the form of an XML file, such as storage, so the WORD file can easily realize transformation from DOC to XML format, and manipulate XML documents is much more convenient, thus realize the has nothing to do with the platform of various operations, through the node, delete, query, substitution of new generation such as WORD file. So, generating a WORD file from a template is the process of replacing a special label in an XML file with user data and saving it as a DOC file.

Here are some of the key steps involved (take a letter of introduction)

Step 1: make WORD templates according to your requirements

Create a new WORD file in DOC format, fill in the template contents as required, set the template format, including font, style, blank line, etc., use special labels (such as: [ does unit name does ]) to fill in the data in advance, and then save the new WORD file as an XML file. In this way, the WORD template is finished. The code is as follows:

< img border = 0 id = theimg onclick = window. The open this. (SRC) SRC = "/ / files.jb51.net/file_images/article/201405/2014515120200242.jpg? 201441512216 ">   Step 2: configure the template information in the configuration file

Add a configuration file named template-rule. XML, with each template node corresponding to a template type. There is a taglist node in each template, and all the child nodes contained by this node contain all the node information to be replaced or deleted in the template. The node information includes: node value, node attribute English name, Chinese description, field type, whether to delete or not. When setting up this configuration file, it is important to note that the value of the desc attribute must be the same as the placeholder in the template XML. For example, the entry item [ does year does ] set in the template XML should correspond to the name of desc=" year "in template-rule. The code is as follows:


<!--?xml version="1.0" encoding="GB2312"?-->
<!--  The template definition  -->
<templates>
    <!--  instructions : S- string ; D- The date of ; E- The amount of ; M- Amount in words ; ifEmptyDelete: T- The value is null to delete the parent node , The default is F -->
    <template name="RECOMMEND-LETTER" desc=" Letter of introduction " templatefile="template4.xml">
        <taglist remark=" List of single value labels ">
            <tag id="1" name="ToPartment" desc=" Receiving department " type="S" ifemptydelete="T">#ToPartment</tag><!-- Receiving department -->
            <tag id="2" name="OwnerName" desc=" The name " type="S">#OwnerName</tag><!-- The name -->
            <tag id="3" name="CountNum" desc=" The number of " type="S">#CountNum</tag><!-- The number of -->
            <tag id="4" name="Business" desc=" content " type="S">#Business</tag><!-- content -->
            <tag id="5" name="UsefulDays" desc=" The period of validity " type="S">#UsefulDays</tag><!-- The period of validity -->
            <tag id="6" name="Year" desc=" years " type="S">#Year</tag><!-- years -->
            <tag id="7" name="Month" desc=" month " type="S">#Month</tag><!-- month -->
            <tag id="8" name="Day" desc=" day " type="S">#Day</tag><!-- day -->
        </taglist>
    </template>
</templates>

Step 3: write Java code



public class RuleDTO {
    
    private String parmName;
    
    private String parmDesc;
    
    private String parmSeq;
    
    private String parmType;
    
    private String parmRegular;
    
    private String parmValue;     
    
    private String ifEmptyDelete;

}



public class Template {

    private String name;//The template name

    private String desc;//Template description

    private String templateFile;//Template file

    private Vector<ruledto> rules;//Template rule

}</ruledto>


public class WordBuilder {

    
    @SuppressWarnings("unchecked")
    public Template loadRules(Map<string, string=""> ruleValue) {
        InputStream in = null;
        Template template = new Template();
        //Rule profile path
        String ruleFile = "template-rule.xml";

        //Template rule name
        String templateRuleName = "";
        try {
            templateRuleName = ruleValue.get("ruleName");
            //Read the template rule file
            in = this.getClass().getClassLoader().getResourceAsStream(ruleFile);
            //Parse template rule
            SAXBuilder sb = new SAXBuilder();
            Document doc = sb.build(in);
            Element root = doc.getRootElement(); //Get the root element
            List<element> templateList = root.getChildren();//All template configurations
            Element element = null;
            Vector<ruledto> rules = null;
            for (int i = 0; i < templateList.size(); i++) {//Iterate through all templates
                element = (Element) templateList.get(i);
                String templateName = element.getAttributeValue("name");
                if (templateRuleName.equalsIgnoreCase(templateName)) {//Finds the given template configuration
                    template.setName(templateName);
                    template.setDesc(element.getAttributeValue("desc"));
                    template.setTemplateFile(element
                            .getAttributeValue("templateFile"));
                    List<element> tagList = ((Element) element.getChildren()
                            .get(0)).getChildren();//The tag list
                    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(" 【 does "
                                + tag.getAttributeValue("desc") + " Does. ");
                        ruleDTO.setParmSeq(tag.getAttributeValue("id"));
                        ruleDTO.setParmType(tag.getAttributeValue("type"));
                        if ("T".equalsIgnoreCase(tag
                                .getAttributeValue("ifEmptyDelete"))) {//Whether the tag can be deleted
                            ruleDTO.setIfEmptyDelete("T");
                        } else {
                            ruleDTO.setIfEmptyDelete("F");
                        }
                        ruleDTO.setParmRegular(tag.getText());
                        //value
                        //Type of judgment parameter
                        String value = (String) ((Map<string, string="">) ruleValue)
                                .get(ruleDTO.getParmRegular().replaceAll("#",
                                        ""));
                        ruleDTO.setParmValue(value);
                        rules.add(ruleDTO);
                    }
                    template.setRules(rules);
                    break;
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (JDOMException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                in.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return template;
    }

    
    public Element findElement(Element currNode, String parentNodeId) {
        //The node is marked as empty
        if (currNode == null || parentNodeId == null) {
            return null;
        }
        Element pNode = null;
        do {
            pNode = currNode.getParent();
            currNode = pNode;
        } while (parentNodeId.equalsIgnoreCase(pNode.getName()));
        return pNode;
    }

    
    @SuppressWarnings("unchecked")
    public String build(Template template) {
        InputStream in = null;
        OutputStream fo = null;
        //The path to the generated file
        String file = "d:\test\" + template.getDesc() + ".doc";
        try {
            //Read template file
            in = this.getClass().getClassLoader()
                    .getResourceAsStream(template.getTemplateFile());
            SAXBuilder sb = new SAXBuilder();
            Document doc = sb.build(in);
            Element root = doc.getRootElement(); //Get the root element
            Namespace ns = root.getNamespace();// NameSpace
            //Word 03 template exists <Wx: sect> The element
            List<element> sectList = root.getChild("body", ns).getChildren();
            Element sectElement = (Element) sectList.get(0);
            //<W: p> The collection of tags under
            List<element> pTagList = sectElement.getChildren("p", ns);
            //<W: tbl> The collection of tags under
            List<element> tblTagList = sectElement.getChildren("tbl", ns);
            if (pTagList != null && pTagList.size() > 0) {
                changeValue4PTag(pTagList, template.getRules(), ns, null);
            }
            if (tblTagList != null && tblTagList.size() > 0) {
                changeValue4TblTag(tblTagList, template.getRules(), ns);
            }
            //Write files
            XMLOutputter outp = new XMLOutputter(" ", true, "UTF-8");
            fo = new FileOutputStream(file);
            outp.output(doc, fo);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (JDOMException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                in.close();
                fo.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return file;
    }

    
    @SuppressWarnings("unchecked")
    private boolean changeValue4PTag(List<element> pTagList,
            Vector<ruledto> rulesValue, Namespace ns, List<element> trChildren) {
        Element p = null;
        boolean delFlag = false;
        for (int i = 0; i < pTagList.size(); i++) {
            boolean delCurrNode = false;//Delete the current node
            boolean delCurrNode4TabWR = false;//Delete the single row node in the table
            p = (Element) pTagList.get(i);
            List<element> pChild = p.getChildren("r", ns);
            for (int j = 0; pChild != null && j < pChild.size(); j++) {
                Element pChildren = (Element) pChild.get(j);
                Element t = pChildren.getChild("t", ns);
                if (t != null) {
                    String text = t.getTextTrim();
                    if (text.indexOf(" 【 does ") != -1) {
                        for (int v = 0; v < rulesValue.size(); v++) {
                            RuleDTO dto = (RuleDTO) rulesValue.get(v);
                            if (text.indexOf(dto.getParmDesc().trim()) != -1) {
                                //Determines whether the property value is nullable
                                if ("T".equals(dto.getIfEmptyDelete())
                                        && StringUtils.isBlank(dto
                                                .getParmValue())) {
                                    //Deletes the node's top-level node
                                    text = "";
                                    if (trChildren != null) {//In view of the <W: tbl> Delete the
                                        Element element = ((Element) p
                                                .getParent()).getParent();
                                        trChildren.remove(element);
                                        delCurrNode4TabWR = true;
                                    } else {//In view of the <W: r> Delete the paragraph
                                            // pTagList.remove(p);
                                        pTagList.remove(pChildren);
                                        delCurrNode = true;
                                    }
                                    break;
                                } else {
                                    text = text.replaceAll(dto.getParmDesc()
                                            .trim(), dto.getParmValue());
                                }
                            }
                        }
                        t.setText(text);
                    }
                    if (delCurrNode4TabWR) {//<W: tbl> The row nodes under the TABLE have been deleted
                        delFlag = true;
                        break;
                    } else if (delCurrNode) {//<W: p> The node under has been deleted
                        i--;
                        delFlag = true;
                        break;
                    }
                }
            }
        }
        return delFlag;
    }

    
    @SuppressWarnings("unchecked")
    private void changeValue4TblTag(List<element> tblTagList,
            Vector<ruledto> rulesValue, Namespace ns) {
        Element p = null;
        for (int i = 0; tblTagList != null && i < tblTagList.size(); i++) {
            p = (Element) tblTagList.get(i);
            List<element> trChildren = p.getChildren("tr", ns);
            for (int j = 0; trChildren != null && j < trChildren.size(); j++) {//Cycle <W: tr>
                Element pChildren = (Element) trChildren.get(j);
                List<element> tcTagList = pChildren.getChildren("tc", ns);
                for (int c = 0; tcTagList != null && c < tcTagList.size(); c++) {//Cycle <W: tc> Take <W: p> A collection of
                    Element tcChildren = (Element) tcTagList.get(c);
                    List<element> pTagList = tcChildren.getChildren("p", ns);
                    boolean delFlag = changeValue4PTag(pTagList, rulesValue,
                            ns, trChildren);
                    if (delFlag) {//The pointer position of trChildren needs to be changed after the row is deleted
                        j--;
                    }
                }
            }
        }
    }

    public static void main(String[] args) throws Exception {
        WordBuilder word = new WordBuilder();
        Map<string, string=""> map = new HashMap<string, string="">();
        //Filling parameters
        map.put("ToPartment", "XXX The company ");
        map.put("OwnerName", " Zhang SAN ");
        map.put("CountNum", "5");
        map.put("Business", " Routine inspection ");
        map.put("UsefulDays", "15");
        map.put("Year", "2014");
        map.put("Month", "5");
        map.put("Day", "13");
        map.put("ruleName", "RECOMMEND-LETTER");
        Template template = word.loadRules(map);
        //Open the file directly
        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></element></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,>

Step 4: done

Several summaries and matters needing attention:

1. The element name defined must be the same as the value corresponding to the same name in the template_rule.xml, otherwise the conversion rules need to be set.

2. The text in the placeholder [ Does does ] defined in the template XML must be the same as the corresponding desc in the template_rule.

3. After the template XML has been configured, you need to check whether the child node under the tag is a tag (related to the WORD version), if not, you must add the tag.

4. If you want to delete a tag node dynamically, the content of that node needs to be on the same line in the template. If not, you can manually adjust the template XML.

5. If you need to realize WORD WORD wrap function (no better WORD wrap scheme in the template has been thought of), you need to first calculate the WORD count of the line of the corresponding template, and then use space to fill.  


Related articles: