1. 程式人生 > 實用技巧 >POI填充word模板內容(文字、表格、圖表)

POI填充word模板內容(文字、表格、圖表)

1,pom引進poi元件(poi官網指出poi4.x.x版本拋棄了jdk1.7之前的版本,所以適應此版本需要將jdk升級)

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>4.1.0</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId> <version>4.1.0</version> </dependency>

2,word模板(template.docx)

3,例項化操作物件(XWPFDocument)

File tpl = new File("template.docx");
if(tpl.exists()){//模板檔案存在
   //讀取模板檔案
   FileInputStream is = new FileInputStream(tpl);    
   XWPFDocument xwpfDocument 
= new XWPFDocument(is); //使用xwpfDocument物件操作word文件 //。。。。。。。。。。。。。 }

4,對文字操作(doParagraph)

/**
     * @Method doParagraph
     * @Description 替換段落內容 (格式有要求:{欄位} 為三個文字物件,找以'{'開始 '}'結尾 中間匹配的欄位替換值)
     * @param dataMap(資料來源)
     * @Return void
     * @Exception
     */
    public void doParagraph(Map<String, Object> dataMap) throws
InvalidFormatException, IOException { if (dataMap != null && dataMap.size() > 0) { List<XWPFParagraph> paragraphs = xwpfDocument.getParagraphs(); for (XWPFParagraph paragraph : paragraphs) { int leftIndex = -1;//'{'的位置索引 int rightIndex = -1;//'}'的位置索引 List<XWPFRun> runs = paragraph.getRuns(); int runIndex=0;//當前位置遊標 for (XWPFRun run : runs) { String text = run.getText(0); if (text != null) { if (text.contains("{")) { leftIndex = runIndex; } if (text.contains("}")) { rightIndex = runIndex; } if(leftIndex>-1 && leftIndex <= rightIndex){ //遍歷{}之間的文字 for(int i=leftIndex;i<=rightIndex;i++){ XWPFRun thisrun=runs.get(i); Object value = dataMap.get(thisrun.getText(0)); if (value != null) { thisrun.setText(value.toString(), 0); } } leftIndex = -1; rightIndex = -1; } } runIndex++; } } } }

5,對錶格操作(doTable)

/**
     * @Method doTable
     * @Description 替換表格內容
     * @param index(表格索引:第幾個表格),dataMap(資料來源)
     * @Return void
     * @Exception
     */
    public void doTable(int index,List<Map<String, Object>> dataMap) throws InvalidFormatException, IOException {
        XWPFTable table = xwpfDocument.getTables().get(index);

        if (dataMap != null && dataMap.size() > 0) {
            List<XWPFTableRow> rows = table.getRows();
            int rowIndex = 0;//尋找欄位繫結行索引
            String[] fields = null;////欄位繫結行欄位順序(a,b,c)
            for (XWPFTableRow row : rows) {
                List<XWPFTableCell> cells = row.getTableCells();
                for (XWPFTableCell cell : cells) {
                    String key = cell.getText()
                            .replaceAll("\\{", "")
                            .replaceAll("}", "");

                    if (dataMap.get(0).get(key) != null) {//找到匹配
                        fields = new String[cells.size()];
                        break;
                    }
                }
                if (fields != null && fields.length>0) {//找到,並獲取欄位
                    for(int i=0;i<fields.length;i++){
                        fields[i] = cells.get(i)
                                         .getText()
                                         .replaceAll("\\{", "")
                                         .replaceAll("}", "");
                    }
                    break;
                }else {
                    rowIndex++;
                }
            }
            if (rowIndex >= 0 && fields != null) {
                //從欄位繫結行開始插入
                for (Map<String, Object> rowdata : dataMap) {
                    XWPFTableRow row = null;
                    try {
                        row = rows.get(rowIndex);
                    } catch (Exception e) {
                        row = table.createRow();
                    }
                    if(row != null) {
                        List<XWPFTableCell> cells = row.getTableCells();
                        int cellIndex = 0;
                        for (XWPFTableCell cell : cells) {
                            cell.removeParagraph(0);
                            XWPFParagraph newPara=cell.addParagraph();
                            XWPFRun run=newPara.createRun();

                            Object value = rowdata.get(fields[cellIndex]);
                            if(value != null){
                                run.setText(value.toString());
                            }

                            cellIndex++;
                        }
                    }
                    rowIndex++;
                }
            }
        }
    }

6,圖表操作(doChart)

/**
     * @Method doChart
     * @Description 替換圖表內容
     * @param index(圖表索引),categoryField 分類軸欄位,seriesField 系列軸欄位,dataMap(資料來源)
     * @Return void
     * @Exception
     */
    public void doChart(int index,
                        String categoryField,//{"a"}
                        String[] seriesField, //{"b","c"}
                        List<Map<String, Object>> dataMap) throws InvalidFormatException, IOException {
        List<XWPFChart> charts= xwpfDocument.getCharts();
        for (XWPFChart chart : charts) {
            //根據圖表索引
            String partname = chart.getPackagePart().getPartName().getName();
            if(partname.contains("chart"+(index+1)+".xml")){

                String[] categories = new String[dataMap.size()];
                Number[][] seriesvalues = new Number[seriesField.length][dataMap.size()];

                int dataIndex = 0;
                for (Map<String, Object> rowdata : dataMap) {
                    categories[dataIndex] = rowdata.get(categoryField).toString();
                    int serieIndex = 0;
                    for(String field:seriesField){
                        Object value = rowdata.get(field);
                        if(value != null){
                            seriesvalues[serieIndex][dataIndex] = (Number) (value);
                        }
                        serieIndex++;
                    }
                    dataIndex++;
                }

                XDDFChartData chartData = chart.getChartSeries().get(0);//目前只做1個chartData情況

                String categoryDataRange = chart.formatRange(new CellRangeAddress(1, categories.length, 0, 0));
                XDDFDataSource<?> categoriesData = XDDFDataSourcesFactory.fromArray(categories, categoryDataRange, 0);

                List<XDDFChartData.Series> series = chartData.getSeries();
                int serieIndex = 0;
                for (XDDFChartData.Series serie:series){
                    String valuesDataRange = chart.formatRange(new CellRangeAddress(1, categories.length, serieIndex + 1, serieIndex + 1));
                    XDDFNumericalDataSource<? extends Number> valuesData = XDDFDataSourcesFactory.fromArray(seriesvalues[serieIndex], valuesDataRange, serieIndex + 1);
                    //賦值
                    serie.replaceData(categoriesData,valuesData);
                    serie.plot();

                    serieIndex++;
                }
            }
        }
    }