亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

 更新時間:2014年05月15日 11:56:42   作者:  
前段時間接到一個Web應用自動生成Word的需求,現(xiàn)整理了下一些關鍵步驟拿來分享一下。

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

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

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

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

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

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

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

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

復制代碼 代碼如下:

<!--?xml version="1.0" encoding="GB2312"?-->
<!-- 模板定義 -->
<templates>
    <!-- 說明: S-字符串; D-日期; E-金額; M-大寫金額; ifEmptyDelete: T-值為空刪除父節(jié)點,默認為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代碼

復制代碼 代碼如下:

/**
 * 參數及規(guī)則
 */
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;//模板規(guī)則

}</ruledto>

復制代碼 代碼如下:

public class WordBuilder {

    /**
     * 根據模板讀取替換規(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ī)則名稱
        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"))) {// 是否可刪除標記
                            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;
    }

    /**
     * 查找父節(jié)點
     */
    public Element findElement(Element currNode, String parentNodeId) {
        // 節(jié)點標示為空
        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>的子節(jié)點<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;// 刪除當前節(jié)點
            boolean delCurrNode4TabWR = false;// 刪除table中單行節(jié)點
            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é)點頂級節(jié)點
                                    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下的行節(jié)點已刪除
                        delFlag = true;
                        break;
                    } else if (delCurrNode) {// <w:p>下的節(jié)點已刪除
                        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++) {// 循環(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="">();
        //填充參數
        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的值一致,否則需要設置轉換規(guī)則。

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

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

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

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

相關文章

  • java解決請求跨域的兩種方法

    java解決請求跨域的兩種方法

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

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

    我們在網站上注冊賬號的時候一般需要獲取驗證碼,而這個驗證碼一般發(fā)送在你的手機號上還有的是發(fā)送在你的郵箱中,注冊,賬號密碼…都需要用到驗證,今天就演示一下如何用SpringBoot整合Mail發(fā)送郵箱
    2021-11-11
  • springboot集成shiro權限管理簡單實現(xiàn)

    springboot集成shiro權限管理簡單實現(xiàn)

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

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

    這篇文章主要介紹了Java編程中面向字符的輸出流,是Java入門學習中的基礎知識,需要的朋友可以參考下
    2015-10-10
  • 全面解析Java設計模式之單例模式

    全面解析Java設計模式之單例模式

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

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

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

    Java三種求水仙花數的方法

    本篇文章通過求水仙花數的實例來讓大家對JAVA求數的概念和方法有更深入的理解和應用,學習參考下吧。
    2018-02-02
  • 使用IDEA異常斷點來定位java.lang.ArrayStoreException的問題

    使用IDEA異常斷點來定位java.lang.ArrayStoreException的問題

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

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

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

    Java線程池必知必會知識點總結

    這篇文章主要給大家介紹了關于Java線程池必知必會知識點的相關資料,文中通過圖文以及實例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2022-02-02

最新評論