使用POI分段落生成純Word動態模板並導入數據

導出數據,可以用word另存爲xml格式的ftl文件,變量用${變量名}表示,然後在類中通過freemarker去替換變量。

但是怎麼導入word數據。發現如果是xml格式,數據格式很易變。如一個標題中如果有中文,後面是個數字,另存成xml時就變成了2個元素了。太鬱悶了。


後來找到方法可以分段落讀入純word文檔。要找到了word基於模板替換的相關例子。於是方案如下。

純word文件變量用${變量名}表示。導出動態模板時,把業務數據替換變量。

導入是分段落讀入數據。


POIReportUtil.java文件


package com.sunrise.wbmp.manage.project.report.util;


import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.*;


import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.model.StyleDescription;
import org.apache.poi.hwpf.model.StyleSheet;
import org.apache.poi.hwpf.usermodel.CharacterProperties;
import org.apache.poi.hwpf.usermodel.Paragraph;
import org.apache.poi.hwpf.usermodel.Range;
import org.apache.poi.hwpf.usermodel.Table;
import org.apache.poi.hwpf.usermodel.TableCell;
import org.apache.poi.hwpf.usermodel.TableIterator;
import org.apache.poi.hwpf.usermodel.TableRow;


public class POIReportUtil {


    public static void main(String[] args) throws Exception {
        Map<String, POIText> replaces = new HashMap<String, POIText>();
        System.out.println("導出數據:");
        
        replaces.put("${projectName}", POIText.str("CMMI"));
        
        replaces.put("${graph1}", POIText.str("rongzhi_li"));
        replaces.put("${內容1}", POIText.str("1123456"));


        replaces.put("${graph2}", POIText.str("graph"));
        replaces.put("${內容2}", POIText.str("2222"));
//
        replaces.put("${graph3}", POIText.str("graph"));
        replaces.put("${內容3}", POIText.str("33333"));


        replaces.put("${graph4}", POIText.str("<END>"));
        replaces.put("${內容4}", POIText.str(""));
        
        for (int i=5;i<10;i++){
            replaces.put("${graph"+i+"}", POIText.str(""));
            replaces.put("${內容"+i+"}", POIText.str(""));
        }


         HWPFDocument hwpf=poiWordTableReplace("E:\\temp\\template\\week_report.doc", replaces);
    FileOutputStream out = new FileOutputStream("E:\\temp\\template\\t2.doc");
    hwpf.write(out);

    out.flush();
    out.close();  
    
    System.out.println("讀入數據:");
    FileInputStream in = new FileInputStream("E:\\temp\\template\\t2.doc");
    HWPFDocument hwpf2 = new HWPFDocument(in);
    Map<String,String> map=readWord( hwpf2);    
    for (Iterator iter=map.entrySet().iterator();iter.hasNext();){
    java.util.Map.Entry entry=(java.util.Map.Entry)iter.next();
    System.out.println(entry.getKey()+":"+entry.getValue());
    }
    }
    public static Map<String,String> readWord(HWPFDocument hwpf
            ) throws Exception {
//        FileInputStream in = new FileInputStream(sourceFile);
//        HWPFDocument hwpf = new HWPFDocument(in);
    Map<String, String> oldMap=new HashMap<String, String>();
        Range r = hwpf.getRange();
        List<String> list = new ArrayList<String>();
        for (int i = 0; i < r.numParagraphs(); i++) {
            Paragraph p = r.getParagraph(i);
            // check if style index is greater than total number of styles
            int numStyles =hwpf.getStyleSheet().numStyles();
            int styleIndex = p.getStyleIndex();
            if (numStyles > styleIndex) {
                StyleSheet style_sheet = hwpf.getStyleSheet();
                StyleDescription style = style_sheet.getStyleDescription(styleIndex);
                String styleName = style.getName();
                if (styleName!=null&&styleName.contains("標題 3")) {
                    // write style name and associated text
                    System.out.println(styleName + " -> " + p.text());
                    //System.out.println(p.text());
                    String text = p.text();
                    text=text.substring(0,text.length()-1);
                    list.add(text);
                    oldMap.put(text, null);
                    if ("<END>".equals(text)){
                    break;
                    }
                }else{
                if (list.size()>0){
                String key=list.get(list.size()-1);
                String oldS=oldMap.get(list.get(list.size()-1));
                String s=( p.text()==null)?"": p.text();
                oldS=(oldS==null)?s:(oldS+s);
                if (oldS!=null && oldS.trim().length()>0){
                oldMap.put(key, oldS);
                }
                }
                }
            }
        }
        return oldMap;
    }    
    public static HWPFDocument poiWordTableReplace(String sourceFile,
            Map<String, POIText> replaces) throws Exception {
        FileInputStream in = new FileInputStream(sourceFile);
        HWPFDocument hwpf = new HWPFDocument(in);
//        Range range = hwpf.getRange();// 得到文檔的讀取範圍
//        TableIterator it = new TableIterator(range);
//        // 迭代文檔中的表格
//        while (it.hasNext()) {
//            Table tb = (Table) it.next();
//            // 迭代行,默認從0開始
//            for (int i = 0; i < tb.numRows(); i++) {
//                TableRow tr = tb.getRow(i);
//                // 迭代列,默認從0開始
//                for (int j = 0; j < tr.numCells(); j++) {
//                    TableCell td = tr.getCell(j);// 取得單元格
//                    // 取得單元格的內容
//                    for (int k = 0; k < td.numParagraphs(); k++) {
//                        Paragraph para = td.getParagraph(k);
//
//                        String s = para.text();
//                        final String old = s;
//                        for (String key : replaces.keySet()) {
//                            if (s.contains(key)) {
//                                s = s.replace(key, replaces.get(key).getText());
//                            }
//                        }
//                        if (!old.equals(s)) {// 有變化
//                            para.replaceText(old, s);
//                            s = para.text();
//                            System.out.println("old:" + old + "->" + "s:" + s);
//                        }
//
//                    } // end for
//                } // end for
//            } // end for
//        } // end while


        Range r = hwpf.getRange();
        CharacterProperties props = new CharacterProperties();
        props.setFontSize(10);
        
        List<String> list = new ArrayList<String>();
        for (int i = 0; i < r.numParagraphs(); i++) {
            Paragraph p = r.getParagraph(i);
            // check if style index is greater than total number of styles
            int numStyles =hwpf.getStyleSheet().numStyles();
            int styleIndex = p.getStyleIndex();
            if (numStyles > styleIndex) {
                StyleSheet style_sheet = hwpf.getStyleSheet();
                StyleDescription style = style_sheet.getStyleDescription(styleIndex);
                String styleName = style.getName();
//                if (styleName!=null&&styleName.contains("標題")) {
//                    // write style name and associated text
//                    //System.out.println(styleName + " -> " + p.text());
//                    System.out.println(p.text());
//                    String text = p.text();
//                    list.add(text);
//                }else{
//                    System.out.println(  p.text());
//                }
                
                System.out.println(  styleName);
                
                String s = p.text();
                final String old = s;
                for (String key : replaces.keySet()) {
                    if (s.contains(key)) {
                        s = s.replace(key, replaces.get(key).getText());
                    }
                }
                if (!old.equals(s)) {// 有變化
                    p.replaceText(old, s);
                    s = p.text();
                    System.out.println("old:" + old + "->" + "s:" + s);
                }




            }
        }
        return hwpf;
    }
}

POIReportUtil.java文件

package com.sunrise.wbmp.manage.project.report.util;


public abstract class POIText {


    public abstract String getText();


    public static POIText str(final String string) {
        return new POIText() {
            @Override
            public String getText() {
                return string;
            }
        };
    }
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章