Niceri

导航

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++;
                }
            }
        }
    }

 

posted on 2020-11-27 17:02  Niceri  阅读(3654)  评论(0编辑  收藏  举报