POI產生WORD文檔,poiword文檔

來源:互聯網
上載者:User

POI產生WORD文檔,poiword文檔

 

POI產生WORD文檔

    POI為Java系處理office文檔的比較優秀的開源庫,其中對於Excel的處理最為優秀,文檔也寫的很詳細。不過很多網友都認為它在word文檔處理方面就遜色很多,不過對於我本次的完成文檔的產生我依然選擇了POI。

需要完成功能配置word模版

採用${xx}方式配置標籤,如果是表格在對應一行一列配置表格名稱

注意在word文檔中,如果兩個相近的字元樣式不同,word預設會儲存在不同的RUN元素中,由此很多朋友在配置好以後都需要儲存為一個單獨的檔案,然後不把不在一起的標籤合并到一個RUN元素中,如果檔案比較大,我相信這絕對是一個比較痛苦的事情,這裡將會側重處理這個問題.我的解決方案是只保留第一RUN的樣式其他的刪掉

解析word模板

首先需要將檔案轉換為XWPFDocument對象,可以通過流的當時,也可以通過opcpackage,不過如果使用opcpackage開啟的方式,開啟的檔案和最終產生的檔案不能夠是同一個檔案,我這裡採用檔案流的方式

public XWPFDocument openDocument() {        XWPFDocument xdoc = null;        InputStream is = null;        try {            is = new FileInputStream(saveFile);            xdoc = new XWPFDocument(is);        } catch (IOException e) {            e.printStackTrace();        }        return xdoc;    }

擷取非列表的標籤,實現方式XWPFDocument對象有當前所有段落以及表格,這裡暫不考慮表格巢狀表格格的情況,每個段落的文本資訊是可以通過p.getText()擷取,擷取段落中文檔配置資訊如下:

   // 擷取段落集合中所有文本    public List<TagInfo> getWordTag(XWPFDocument doc, String regex) {        List<TagInfo> tags = new ArrayList<TagInfo>();        // 普通段落        List<XWPFParagraph> pars = doc.getParagraphs();        for (int i = 0; i < pars.size(); i++) {            XWPFParagraph p = pars.get(i);            setTagInfoList(tags, p, regex);        }        // Table中段落        List<XWPFTable> commTables = getDocTables(doc, false, regex);        for (XWPFTable table : commTables) {            List<XWPFParagraph> tparags = getTableParagraph(table);            for (int i = 0; i < tparags.size(); i++) {                XWPFParagraph p = tparags.get(i);                setTagInfoList(tags, p, regex);            }        }        return tags;    }

擷取文本後通過正則解析,並依次儲存到TagInfo中

// 向 taglist中添加新解析的段落資訊    private void setTagInfoList(List<TagInfo> list, XWPFParagraph p,            String regex) {        if (regex == "")            regex = defaultRegex;        Pattern pattern = Pattern.compile(regex);        Matcher matcher = pattern.matcher(p.getText());        int startPosition = 0;        while (matcher.find(startPosition)) {            String match = matcher.group();            if (!list.contains(new TagInfo(match, match, ""))) {                list.add(new TagInfo(match, match, ""));            }            startPosition = matcher.end();        }    }

解析表格

    // 擷取Table列表中的配置資訊    public Map<String, List<List<TagInfo>>> getTableTag(XWPFDocument doc,            String regex) {        Map<String, List<List<TagInfo>>> mapList = new HashMap<String, List<List<TagInfo>>>();        List<XWPFTable> lstTables = getDocTables(doc, true, regex);        for (XWPFTable table : lstTables) {            // 擷取每個表格第一個儲存格,以及最後一行            String strTableName = getTableListName(table, regex);            List<List<TagInfo>> list = new ArrayList<List<TagInfo>>();            List<TagInfo> lstTag = new ArrayList<TagInfo>();            int rowSize = table.getRows().size();            XWPFTableRow lastRow = table.getRow(rowSize - 1);            for (XWPFTableCell cell : lastRow.getTableCells()) {                for (XWPFParagraph p : cell.getParagraphs()) {                    // 去掉空白字串                    if (p.getText() != null && p.getText().length() > 0) {                        setTagInfoList(lstTag, p, regex);                    }                }            }            list.add(lstTag);            // 添加到資料集            mapList.put(strTableName, list);        }        return mapList;    }
產生WORD文檔

痛點替換標籤
傳入資料格式包含三個formtag以及一個tableTag

{"formTags":
[{"TagName":"${xxxx}","TagText":"${xxxx}","TagValue":""},
{"TagName":"${123}","TagText":"${123}","TagValue":""},
{"TagName":"${ddd}","TagText":"${ddd}","TagValue":""}],
"tableTags":{
"${table}":[
[{"TagName":"${COL1}","TagText":"${COL1}","TagValue":""},{"TagName":"${COL2}","TagText":"${COL2}","TagValue":""}]
]}
}

普通文檔產生,並且保留配置樣式,這裡主要使用POI中提供searchText方法,返回Tag所有所在的RUN標籤,通過一個字元做比較,如果找的第一個匹配的文本開始計數,所有在當前條件下類型 $${xxx}這樣的標籤是無法實現替換的
替換普通文本Tag

    public void ReplaceInParagraph(List<TagInfo> tagList, XWPFParagraph para,            String regex) {        if (regex == "")            regex = defaultRegex;        List<XWPFRun> runs = para.getRuns();        for (TagInfo ti : tagList) {            String find = ti.TagText;            String replValue = ti.TagValue;            TextSegement found = para.searchText(find,                    new PositionInParagraph());            if (found != null) {                // 判斷尋找內容是否在同一個Run標籤中                if (found.getBeginRun() == found.getEndRun()) {                    XWPFRun run = runs.get(found.getBeginRun());                    String runText = run.getText(run.getTextPosition());                    String replaced = runText.replace(find, replValue);                    run.setText(replaced, 0);                } else {                    // 存在多個Run標籤                    StringBuilder sb = new StringBuilder();                    for (int runPos = found.getBeginRun(); runPos <= found                            .getEndRun(); runPos++) {                        XWPFRun run = runs.get(runPos);                        sb.append(run.getText((run.getTextPosition())));                    }                    String connectedRuns = sb.toString();                    String replaced = connectedRuns.replace(find, replValue);                    XWPFRun firstRun = runs.get(found.getBeginRun());                    firstRun.setText(replaced, 0);                    // 刪除後邊的run標籤                    for (int runPos = found.getBeginRun() + 1; runPos <= found                            .getEndRun(); runPos++) {                        // 清空其他標籤內容                        XWPFRun partNext = runs.get(runPos);                        partNext.setText("", 0);                    }                }            }        }        // 完成第一遍尋找,檢測段落中的標籤是否已經替換完        Pattern pattern = Pattern.compile(regex);        Matcher matcher = pattern.matcher(para.getText());        boolean find = matcher.find();        if (find) {            ReplaceInParagraph(tagList, para, regex);            find = false;        }    }

表格主要是通過複製模版行,然後對模版行中的內容做修改
複製文字標籤RUN

    private void CopyRun(XWPFRun target, XWPFRun source) {        target.getCTR().setRPr(source.getCTR().getRPr());        // 設定文本        target.setText(source.text());    }

複製段落XWPFParagraph

    private void copyParagraph(XWPFParagraph target, XWPFParagraph source) {        // 設定段落樣式        target.getCTP().setPPr(source.getCTP().getPPr());        // 添加Run標籤        for (int pos = 0; pos < target.getRuns().size(); pos++) {            target.removeRun(pos);        }        for (XWPFRun s : source.getRuns()) {            XWPFRun targetrun = target.createRun();            CopyRun(targetrun, s);        }    }

複製儲存格XWPFTableCell

    private void copyTableCell(XWPFTableCell target, XWPFTableCell source) {        // 列屬性        target.getCTTc().setTcPr(source.getCTTc().getTcPr());        // 刪除目標 targetCell 所有儲存格        for (int pos = 0; pos < target.getParagraphs().size(); pos++) {            target.removeParagraph(pos);        }        // 添加段落        for (XWPFParagraph sp : source.getParagraphs()) {            XWPFParagraph targetP = target.addParagraph();            copyParagraph(targetP, sp);        }    }

複製行XWPFTableRow

    private void CopytTableRow(XWPFTableRow target, XWPFTableRow source) {        // 複製樣式        target.getCtRow().setTrPr(source.getCtRow().getTrPr());        // 複製儲存格        for (int i = 0; i < target.getTableCells().size(); i++) {            copyTableCell(target.getCell(i), source.getCell(i));        }    }

著作權,轉載請說明來源 楊瀚博
以上就完成所有功能更,只要你配置規範,可以完全原樣輸出模版內容。這裡特別感謝下肖哥哥大力支援。
其次,java的編碼真的讓人很無語,get或post時中文各種亂碼

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.