一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - 一個JAVA小項目--Web應用自動生成Word

一個JAVA小項目--Web應用自動生成Word

2019-11-23 17:00Java教程網 JAVA教程

前段時間接到一個Web應用自動生成Word的需求,現整理了下一些關鍵步驟拿來分享一下。

前段時間接到一個Web應用自動生成Word的需求,現整理了下一些關鍵步驟拿來分享一下。

思路:(注:這里只針對WORD2003版本,其它版本大同小異。)

因為WORD文件內部的數據及格式等是通過XML文件的形式存儲的,所以WORD文件可以很方便的實現由DOC到XML格式的相互轉換,而操作XML文件就方便的多了,這樣就實現了與平臺無關的各種操作,通過節點的查詢、替換、刪除、新增等生成Word文件。所以,根據模板生成WORD文件實質就是由用戶數據替換XML文件中特殊標簽,然后另存為一個DOC文件的過程。

下面列舉涉及到的一些關鍵步驟(以介紹信為例)

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

新建一個DOC格式的WORD文件,根據需要填寫好模板內容,設置好模板的格式,包括字體,樣式,空行等等,需要填充的數據使用特殊標簽(如:【※單位名稱※】)預先占位,然后將新建的WORD文件另存為XML格式文件。這樣, WORD模板就制作完成了,代碼如下:

一個JAVA小項目--Web應用自動生成Word

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

 

新增名為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;//模板規則

}</ruledto>

 

 

復制代碼代碼如下:

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 = (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) {
        // 節點標示為空
        if (currNode == null || parentNodeId == null) {
            return null;
        }
        Element pNode = null;
        do {
            pNode = currNode.getParent();
            currNode = pNode;
        } while (parentNodeId.equalsIgnoreCase(pNode.getName()));
        return pNode;
    }

    /**
     * 生成Word文件
     */
    @SuppressWarnings("unchecked")
    public String build(Template template) {
        InputStream in = null;
        OutputStream fo = null;
        // 生成文件的路徑
        String file = "d:\\test\\" + template.getDesc() + ".doc";
        try {
            // 讀取模板文件
            in = this.getClass().getClassLoader()
                    .getResourceAsStream(template.getTemplateFile());
            SAXBuilder sb = new SAXBuilder();
            Document doc = sb.build(in);
            Element root = doc.getRootElement(); // 得到根元素
            Namespace ns = root.getNamespace();// NameSpace
            // word 03模板存在<wx:sect>元素
            List<element> sectList = root.getChild("body", ns).getChildren();
            Element sectElement = (Element) sectList.get(0);
            // <w:p>下的標簽集合
            List<element> pTagList = sectElement.getChildren("p", ns);
            // <w:tbl>下的標簽集合
            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);
            }
            // 寫文件
            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;
    }

    /**
     * 針對<w:body><wx:sect><w:p>這種層級的WORD模板, 查找及替換<w:p>下的標簽。
     * @param pTagList :<w:p>集合
     * @param rulesValue :RuleDTO集合
     * @param ns :NameSpace對象
     * @param trChildren :<w:tbl>的子節點<w:tr>集合
     */
    @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;// 刪除當前節點
            boolean delCurrNode4TabWR = false;// 刪除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("【※") != -1) {
                        for (int v = 0; v < rulesValue.size(); v++) {
                            RuleDTO dto = (RuleDTO) rulesValue.get(v);
                            if (text.indexOf(dto.getParmDesc().trim()) != -1) {
                                // 判斷屬性值是否為可空刪除
                                if ("T".equals(dto.getIfEmptyDelete())
                                        && StringUtils.isBlank(dto
                                                .getParmValue())) {
                                    // 刪除該節點頂級節點
                                    text = "";
                                    if (trChildren != null) {// 針對<w:tbl>刪除該行
                                        Element element = ((Element) p
                                                .getParent()).getParent();
                                        trChildren.remove(element);
                                        delCurrNode4TabWR = true;
                                    } else {// 針對<w:r>刪除段
                                            // 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>TABLE下的行節點已刪除
                        delFlag = true;
                        break;
                    } else if (delCurrNode) {// <w:p>下的節點已刪除
                        i--;
                        delFlag = true;
                        break;
                    }
                }
            }
        }
        return delFlag;
    }

    /**
     * 針對含有表格的WORD模板, 查找及替換<w:tbl>下的標簽。
     * @param tblTagList :<w:tbl>集合
     * @param rulesValue :RuleDTO集合
     * @param ns :NameSpace對象
     */
    @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++) {// 循環<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++) {// 循環<w:tc>取<w:p>集合
                    Element tcChildren = (Element) tcTagList.get(c);
                    List<element> pTagList = tcChildren.getChildren("p", ns);
                    boolean delFlag = changeValue4PTag(pTagList, rulesValue,
                            ns, trChildren);
                    if (delFlag) {// 刪除行后需要改變trChildren的指針位置
                        j--;
                    }
                }
            }
        }
    }

    public static void main(String[] args) throws Exception {
        WordBuilder word = new WordBuilder();
        Map<string, string=""> map = new HashMap<string, string="">();
        //填充參數
        map.put("ToPartment", "XXX公司");
        map.put("OwnerName", "張三");
        map.put("CountNum", "5");
        map.put("Business", "例行檢查");
        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);
        //直接打開文件
        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,>

 

第四步:大功告成

幾點總結及注意事項:

1. 定義的元素name必須與template_rule.xml中對應相同的name的值一致,否則需要設置轉換規則。

2. 模板xml中定義的占位符【※※】中的文字必須與template_rule.xml中對應的desc相同,否則需要設置轉換規則.

3. 在配置好模板XML后,需要檢查標簽下的子節點是否是標簽(與WORD版本有關),如果沒有,則必須加上該標簽。

4. 如果要動態刪除標簽節點,則這個節點的內容需要在模板中的同一行,如果不是,則可以手動調整模板XML。

5. 如果需要實現WORD自動換行功能(關于模板中換行的方案暫沒有想到更好的),則需要首先計算出對應模板該行的字數,然后采用空格填充來實現。 

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 14一18cad中国大学生 | 男人狂擦女人的下面视频 | 亚洲人成网站在线观看90影院 | 国产一级毛片外aaaa | 国产亚洲精品综合在线网址 | 被夫上司侵犯了中文字幕 | 韩国丽卡三级作品 | 久久理论片迅播影院一级 | 亚洲精品国产A久久久久久 亚洲精品福利一区二区在线观看 | 大学生特黄特色大片免费播放 | 四川女人偷人真实视频 | 高黄h文各种play | aaa一级特黄 | 极品一区 | 69日本xxxxxxxxx98 69人成网站色www | 青青青国产精品国产精品美女 | 青草视频免费观看 | ckinese中国男同gay男男 | 丝袜捆绑调教丨vk | 日产精品一卡2卡三卡4乱码久久 | 精品一区二区三区免费站 | 亚洲日本va午夜中文字幕 | 精品日韩一区 | 九九热精品免费观看 | 99久久久久国产精品免费 | 欧美精品国产一区二区 | 精品一久久香蕉国产二月 | 欧美日韩亚洲国内综合网俺 | 青青草精品 | 大胆国模一区二区三区伊人 | 美女被网站 | 国产馆精品推荐在线观看 | 日本色吧 | 水野朝阳厨房系列在线观看 | 日本a在线天堂 | 天天曰天天干 | 91夜夜人人揉人人捏人人添 | 小小水蜜桃视频高清在线观看免费 | 6080窝窝理论 | 亚洲天堂视频在线播放 | 四虎成人免费 |