欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一個(gè)JAVA小項(xiàng)目--Web應(yīng)用自動(dòng)生成Word

 更新時(shí)間:2014年05月15日 11:56:42   作者:  
前段時(shí)間接到一個(gè)Web應(yīng)用自動(dòng)生成Word的需求,現(xiàn)整理了下一些關(guān)鍵步驟拿來(lái)分享一下。

前段時(shí)間接到一個(gè)Web應(yīng)用自動(dòng)生成Word的需求,現(xiàn)整理了下一些關(guān)鍵步驟拿來(lái)分享一下。

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

因?yàn)閃ORD文件內(nèi)部的數(shù)據(jù)及格式等是通過(guò)XML文件的形式存儲(chǔ)的,所以WORD文件可以很方便的實(shí)現(xiàn)由DOC到XML格式的相互轉(zhuǎn)換,而操作XML文件就方便的多了,這樣就實(shí)現(xiàn)了與平臺(tái)無(wú)關(guān)的各種操作,通過(guò)節(jié)點(diǎn)的查詢、替換、刪除、新增等生成Word文件。所以,根據(jù)模板生成WORD文件實(shí)質(zhì)就是由用戶數(shù)據(jù)替換XML文件中特殊標(biāo)簽,然后另存為一個(gè)DOC文件的過(guò)程。

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

第一步:根據(jù)需求制作WORD模板

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

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

新增名為template-rule.xml的配置文件,每個(gè)template節(jié)點(diǎn)對(duì)應(yīng)一個(gè)模板類(lèi)型。每個(gè)template中有一個(gè)taglist節(jié)點(diǎn),該節(jié)點(diǎn)包含的所有子節(jié)點(diǎn)包含了模板所有將要替換、刪除節(jié)點(diǎn)信息,節(jié)點(diǎn)信息包括:節(jié)點(diǎn)值,節(jié)點(diǎn)屬性英文名稱(chēng),中文描述,字段類(lèi)型,可否刪除等信息。在設(shè)置這個(gè)配置文件時(shí)候,需要注意desc屬性的值必須與模板X(qián)ML中的占位符一致。比如:模板X(qián)ML中設(shè)置的年份這個(gè)錄入項(xiàng)【※年※】需與template-rule.xml中的desc="年"名稱(chēng)對(duì)應(yīng),代碼如下:

復(fù)制代碼 代碼如下:

<!--?xml version="1.0" encoding="GB2312"?-->
<!-- 模板定義 -->
<templates>
    <!-- 說(shuō)明: S-字符串; D-日期; E-金額; M-大寫(xiě)金額; ifEmptyDelete: T-值為空刪除父節(jié)點(diǎn),默認(rèn)為F -->
    <template name="RECOMMEND-LETTER" desc="介紹信" templatefile="template4.xml">
        <taglist remark="單值標(biāo)簽列表">
            <tag id="1" name="ToPartment" desc="接收部門(mén)" type="S" ifemptydelete="T">#ToPartment</tag><!--接收部門(mén)-->
            <tag id="2" name="OwnerName" desc="姓名" type="S">#OwnerName</tag><!--姓名-->
            <tag id="3" name="CountNum" desc="人數(shù)" type="S">#CountNum</tag><!--人數(shù)-->
            <tag id="4" name="Business" desc="內(nèi)容" type="S">#Business</tag><!--內(nèi)容-->
            <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>

第三步:編寫(xiě)java代碼

復(fù)制代碼 代碼如下:

/**
 * 參數(shù)及規(guī)則
 */
public class RuleDTO {
    /**
     * tag名稱(chēng)
     */
    private String parmName;
    /**
     * tag描述
     */
    private String parmDesc;
    /**
     * tag序號(hào)
     */
    private String parmSeq;
    /**
     * tag值類(lèi)型
     */
    private String parmType;
    /**
     * tag參數(shù)名稱(chēng)
     */
    private String parmRegular;
    /**
     * tag值
     */
    private String parmValue;    
    /**
     * tag值為空刪除該屬性
     */
    private String ifEmptyDelete;

}

復(fù)制代碼 代碼如下:

/**
 * 描述: Word模板信息
 */
public class Template {

    private String name;//模板名

    private String desc;//模板描述

    private String templateFile;//模板文件

    private Vector<ruledto> rules;//模板規(guī)則

}</ruledto>

復(fù)制代碼 代碼如下:

public class WordBuilder {

    /**
     * 根據(jù)模板讀取替換規(guī)則
     * @param templateName  模板ID
     */
    @SuppressWarnings("unchecked")
    public Template loadRules(Map<string, string=""> ruleValue) {
        InputStream in = null;
        Template template = new Template();
        // 規(guī)則配置文件路徑
        String ruleFile = "template-rule.xml";

        // 模板規(guī)則名稱(chēng)
        String templateRuleName = "";
        try {
            templateRuleName = ruleValue.get("ruleName");
            // 讀取模板規(guī)則文件
            in = this.getClass().getClassLoader().getResourceAsStream(ruleFile);
            // 解析模板規(guī)則
            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"))) {// 是否可刪除標(biāo)記
                            ruleDTO.setIfEmptyDelete("T");
                        } else {
                            ruleDTO.setIfEmptyDelete("F");
                        }
                        ruleDTO.setParmRegular(tag.getText());
                        // 值
                        // 判斷參數(shù)類(lèi)型
                        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;
    }

    /**
     * 查找父節(jié)點(diǎn)
     */
    public Element findElement(Element currNode, String parentNodeId) {
        // 節(jié)點(diǎn)標(biāo)示為空
        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>下的標(biāo)簽集合
            List<element> pTagList = sectElement.getChildren("p", ns);
            // <w:tbl>下的標(biāo)簽集合
            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);
            }
            // 寫(xiě)文件
            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;
    }

    /**
     * 針對(duì)<w:body><wx:sect><w:p>這種層級(jí)的WORD模板, 查找及替換<w:p>下的標(biāo)簽。
     * @param pTagList :<w:p>集合
     * @param rulesValue :RuleDTO集合
     * @param ns :NameSpace對(duì)象
     * @param trChildren :<w:tbl>的子節(jié)點(diǎn)<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;// 刪除當(dāng)前節(jié)點(diǎn)
            boolean delCurrNode4TabWR = false;// 刪除table中單行節(jié)點(diǎn)
            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())) {
                                    // 刪除該節(jié)點(diǎn)頂級(jí)節(jié)點(diǎn)
                                    text = "";
                                    if (trChildren != null) {// 針對(duì)<w:tbl>刪除該行
                                        Element element = ((Element) p
                                                .getParent()).getParent();
                                        trChildren.remove(element);
                                        delCurrNode4TabWR = true;
                                    } else {// 針對(duì)<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下的行節(jié)點(diǎn)已刪除
                        delFlag = true;
                        break;
                    } else if (delCurrNode) {// <w:p>下的節(jié)點(diǎn)已刪除
                        i--;
                        delFlag = true;
                        break;
                    }
                }
            }
        }
        return delFlag;
    }

    /**
     * 針對(duì)含有表格的WORD模板, 查找及替換<w:tbl>下的標(biāo)簽。
     * @param tblTagList :<w:tbl>集合
     * @param rulesValue :RuleDTO集合
     * @param ns :NameSpace對(duì)象
     */
    @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++) {// 循環(huán)<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++) {// 循環(huán)<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="">();
        //填充參數(shù)
        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);
        //直接打開(kāi)文件
        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,>

第四步:大功告成

幾點(diǎn)總結(jié)及注意事項(xiàng):

1. 定義的元素name必須與template_rule.xml中對(duì)應(yīng)相同的name的值一致,否則需要設(shè)置轉(zhuǎn)換規(guī)則。

2. 模板xml中定義的占位符【※※】中的文字必須與template_rule.xml中對(duì)應(yīng)的desc相同,否則需要設(shè)置轉(zhuǎn)換規(guī)則.

3. 在配置好模板X(qián)ML后,需要檢查標(biāo)簽下的子節(jié)點(diǎn)是否是標(biāo)簽(與WORD版本有關(guān)),如果沒(méi)有,則必須加上該標(biāo)簽。

4. 如果要?jiǎng)討B(tài)刪除標(biāo)簽節(jié)點(diǎn),則這個(gè)節(jié)點(diǎn)的內(nèi)容需要在模板中的同一行,如果不是,則可以手動(dòng)調(diào)整模板X(qián)ML。

5. 如果需要實(shí)現(xiàn)WORD自動(dòng)換行功能(關(guān)于模板中換行的方案暫沒(méi)有想到更好的),則需要首先計(jì)算出對(duì)應(yīng)模板該行的字?jǐn)?shù),然后采用空格填充來(lái)實(shí)現(xiàn)。 

相關(guān)文章

  • java解決請(qǐng)求跨域的兩種方法

    java解決請(qǐng)求跨域的兩種方法

    這篇文章主要為大家詳細(xì)介紹了java解決請(qǐng)求跨域的兩種方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-08-08
  • SpringBoot整合Mail發(fā)送郵件功能

    SpringBoot整合Mail發(fā)送郵件功能

    我們?cè)诰W(wǎng)站上注冊(cè)賬號(hào)的時(shí)候一般需要獲取驗(yàn)證碼,而這個(gè)驗(yàn)證碼一般發(fā)送在你的手機(jī)號(hào)上還有的是發(fā)送在你的郵箱中,注冊(cè),賬號(hào)密碼…都需要用到驗(yàn)證,今天就演示一下如何用SpringBoot整合Mail發(fā)送郵箱
    2021-11-11
  • springboot集成shiro權(quán)限管理簡(jiǎn)單實(shí)現(xiàn)

    springboot集成shiro權(quán)限管理簡(jiǎn)單實(shí)現(xiàn)

    這篇文章主要介紹了springboot集成shiro權(quán)限管理簡(jiǎn)單實(shí)現(xiàn),文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-08-08
  • 詳解Java編程中面向字符的輸出流

    詳解Java編程中面向字符的輸出流

    這篇文章主要介紹了Java編程中面向字符的輸出流,是Java入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-10-10
  • 全面解析Java設(shè)計(jì)模式之單例模式

    全面解析Java設(shè)計(jì)模式之單例模式

    這篇文章主要幫助大家全面解析Java設(shè)計(jì)模式之單例模式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • Java利用遞歸算法實(shí)現(xiàn)查詢斐波那契數(shù)

    Java利用遞歸算法實(shí)現(xiàn)查詢斐波那契數(shù)

    今天小編就為大家分享一篇關(guān)于Java利用遞歸算法實(shí)現(xiàn)查詢斐波那契數(shù),小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2018-12-12
  • Java三種求水仙花數(shù)的方法

    Java三種求水仙花數(shù)的方法

    本篇文章通過(guò)求水仙花數(shù)的實(shí)例來(lái)讓大家對(duì)JAVA求數(shù)的概念和方法有更深入的理解和應(yīng)用,學(xué)習(xí)參考下吧。
    2018-02-02
  • 使用IDEA異常斷點(diǎn)來(lái)定位java.lang.ArrayStoreException的問(wèn)題

    使用IDEA異常斷點(diǎn)來(lái)定位java.lang.ArrayStoreException的問(wèn)題

    這篇文章主要介紹了使用IDEA異常斷點(diǎn)來(lái)定位java.lang.ArrayStoreException的問(wèn)題,平常開(kāi)發(fā)過(guò)程中面對(duì)這種描述不夠清楚,無(wú)法定位具體原因的問(wèn)題該如何處理,下面我們來(lái)一起學(xué)習(xí)一下吧
    2019-06-06
  • Java多線程實(shí)現(xiàn)方塊賽跑小游戲

    Java多線程實(shí)現(xiàn)方塊賽跑小游戲

    這篇文章主要為大家詳細(xì)介紹了Java多線程實(shí)現(xiàn)方塊賽跑小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-07-07
  • Java線程池必知必會(huì)知識(shí)點(diǎn)總結(jié)

    Java線程池必知必會(huì)知識(shí)點(diǎn)總結(jié)

    這篇文章主要給大家介紹了關(guān)于Java線程池必知必會(huì)知識(shí)點(diǎn)的相關(guān)資料,文中通過(guò)圖文以及實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2022-02-02

最新評(píng)論