zoukankan      html  css  js  c++  java
  • 读取word模板,填充数据后导出

    一、需求说明

          定期生成word报告,报告中含有文本、表格、图表等元素,依次获取进行替换,保留原有样式,生成新的word文档

    二、引入依赖

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

    三、word模板样式

     类似此种样式,有文本、图表、表格

    四、代码

    4.1 工具类

    import java.io.IOException;
    import java.io.OutputStream;
    import java.math.BigDecimal;
    import java.math.BigInteger;
    import java.util.List;
    import java.util.Map;
    
    import org.apache.poi.ooxml.POIXMLDocumentPart;
    import org.apache.poi.ss.usermodel.Sheet;
    import org.apache.poi.ss.usermodel.Workbook;
    import org.apache.poi.ss.util.CellRangeAddress;
    import org.apache.poi.xssf.usermodel.XSSFWorkbook;
    import org.apache.poi.xwpf.usermodel.XWPFChart;
    import org.apache.poi.xwpf.usermodel.XWPFTableCell;
    import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxDataSource;
    import org.openxmlformats.schemas.drawingml.x2006.chart.CTBarChart;
    import org.openxmlformats.schemas.drawingml.x2006.chart.CTBarSer;
    import org.openxmlformats.schemas.drawingml.x2006.chart.CTChart;
    import org.openxmlformats.schemas.drawingml.x2006.chart.CTLineChart;
    import org.openxmlformats.schemas.drawingml.x2006.chart.CTLineSer;
    import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumData;
    import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumDataSource;
    import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumVal;
    import org.openxmlformats.schemas.drawingml.x2006.chart.CTPieChart;
    import org.openxmlformats.schemas.drawingml.x2006.chart.CTPieSer;
    import org.openxmlformats.schemas.drawingml.x2006.chart.CTPlotArea;
    import org.openxmlformats.schemas.drawingml.x2006.chart.CTStrData;
    import org.openxmlformats.schemas.drawingml.x2006.chart.CTStrVal;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTColor;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFonts;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHpsMeasure;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTJc;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTOnOff;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPr;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTParaRPr;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPr;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTShd;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcPr;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTText;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTVerticalJc;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.STJc;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.STOnOff;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.STVerticalJc;
    
    /**
     * poi生成word的工具类
     */
    public class PoiWordTools {
    
        private static final BigDecimal bd2 = new BigDecimal("2");
    
    
        /**
         * 调用替换柱状图数据
         */
        public  static void replaceBarCharts(POIXMLDocumentPart poixmlDocumentPart,
                                            List<String> titleArr, List<String> fldNameArr, List<Map<String, String>> listItemsByType) {
            XWPFChart chart = (XWPFChart) poixmlDocumentPart;
            chart.getCTChart();
    
            //根据属性第一列名称切换数据类型
            CTChart ctChart = chart.getCTChart();
            CTPlotArea plotArea = ctChart.getPlotArea();
    
            CTBarChart barChart = plotArea.getBarChartArray(0);
            List<CTBarSer> BarSerList = barChart.getSerList();  // 获取柱状图单位
    
            //刷新内置excel数据
            refreshExcel(chart, listItemsByType, fldNameArr, titleArr);
            //刷新页面显示数据
            refreshBarStrGraphContent(barChart, BarSerList, listItemsByType, fldNameArr, 1);
    
        }
        
        
        /**
         * 双柱图
         */
        public void replaceTwoBarCharts(POIXMLDocumentPart poixmlDocumentPart,
                List<String> titleArr, List<String> fldNameArr, List<Map<String, String>> listItemsByType) {
                XWPFChart chart = (XWPFChart) poixmlDocumentPart;
                chart.getCTChart();
                
                //根据属性第一列名称切换数据类型
                CTChart ctChart = chart.getCTChart();
                CTPlotArea plotArea = ctChart.getPlotArea();
                
                CTBarChart barChart = plotArea.getBarChartArray(0);
                List<CTBarSer> BarSerList = barChart.getSerList();  // 获取柱状图单位
                
                //刷新内置excel数据
                refreshExcel(chart, listItemsByType, fldNameArr, titleArr);
                //刷新页面显示数据
                refreshBarStrGraphContent(barChart, BarSerList, listItemsByType, fldNameArr, 1);
                
                CTBarChart barCharttwo = plotArea.getBarChartArray(0);
                List<CTBarSer> BarSerListtwo = barChart.getSerList();  // 获取柱状图单位
                
                //刷新内置excel数据
                refreshExcel(chart, listItemsByType, fldNameArr, titleArr);
                //刷新页面显示数据
                refreshBarStrGraphContent(barCharttwo, BarSerListtwo, listItemsByType, fldNameArr, 2);
    
    }
        
        
    
    
    
        /**
         * 调用替换折线图数据
         */
        public static void replaceLineCharts(POIXMLDocumentPart poixmlDocumentPart,
                                             List<String> titleArr, List<String> fldNameArr, List<Map<String, String>> listItemsByType) {
            XWPFChart chart = (XWPFChart) poixmlDocumentPart;
            chart.getCTChart();
    
            //根据属性第一列名称切换数据类型
            CTChart ctChart = chart.getCTChart();
            CTPlotArea plotArea = ctChart.getPlotArea();
    
            CTLineChart lineChart = plotArea.getLineChartArray(0);
            List<CTLineSer> lineSerList = lineChart.getSerList();   // 获取折线图单位
    
            //刷新内置excel数据
            refreshExcel(chart, listItemsByType, fldNameArr, titleArr);
            //刷新页面显示数据
            refreshLineStrGraphContent(lineChart, lineSerList, listItemsByType, fldNameArr, 1);
    
        }
    
    
        /**
         * 调用替换饼图数据
         */
        public  void replacePieCharts(POIXMLDocumentPart poixmlDocumentPart,
                                             List<String> titleArr, List<String> fldNameArr, List<Map<String, String>> listItemsByType) {
            XWPFChart chart = (XWPFChart) poixmlDocumentPart;
            chart.getCTChart();
    
            //根据属性第一列名称切换数据类型
            CTChart ctChart = chart.getCTChart();
            CTPlotArea plotArea = ctChart.getPlotArea();
    
            CTPieChart pieChart = plotArea.getPieChartArray(0);
            List<CTPieSer> pieSerList = pieChart.getSerList();  // 获取饼图单位
    
            //刷新内置excel数据
            refreshExcel(chart, listItemsByType, fldNameArr, titleArr);
            //刷新页面显示数据
            refreshPieStrGraphContent(pieChart, pieSerList, listItemsByType, fldNameArr, 1);
    
        }
    
    
        /**
         * 调用替换柱状图、折线图组合数据
         */
        public  void replaceCombinationCharts(POIXMLDocumentPart poixmlDocumentPart,
                                            List<String> titleArr, List<String> fldNameArr, List<Map<String, String>> listItemsByType) {
            XWPFChart chart = (XWPFChart) poixmlDocumentPart;
            chart.getCTChart();
    
            //根据属性第一列名称切换数据类型
            CTChart ctChart = chart.getCTChart();
            CTPlotArea plotArea = ctChart.getPlotArea();
            CTBarChart barChart = plotArea.getBarChartArray(0);
            List<CTBarSer> barSerList = barChart.getSerList();  // 获取柱状图单位
            //刷新内置excel数据
           refreshExcel(chart, listItemsByType, fldNameArr, titleArr);
            //刷新页面显示数据
            refreshBarStrGraphContent(barChart, barSerList, listItemsByType, fldNameArr, 1);
    
    
            CTLineChart lineChart = plotArea.getLineChartArray(0);
            List<CTLineSer> lineSerList = lineChart.getSerList();   // 获取折线图单位
            //刷新内置excel数据
            refreshExcel(chart, listItemsByType, fldNameArr, titleArr);
            //刷新页面显示数据
            refreshLineStrGraphContent(lineChart, lineSerList, listItemsByType, fldNameArr, 2);
    
        }
    
    
        /**
         * 刷新折线图数据方法
         *
         * @param typeChart
         * @param serList
         * @param dataList
         * @param fldNameArr
         * @param titleArr
         * @param showtailArr
         * @param ispercentArr
         * @param position
         * @return
         */
        public static boolean refreshLineStrGraphContent(Object typeChart,
                                                         List<?> serList, List<Map<String, String>> dataList, List<String> fldNameArr, int position) {
    
            boolean result = true;
            //更新数据区域
            for (int i = 0; i < serList.size(); i++) {
                //CTSerTx tx=null;
                CTAxDataSource cat = null;
                CTNumDataSource val = null;
                CTLineSer ser = ((CTLineChart) typeChart).getSerArray(i);
                //tx= ser.getTx();
                // Category Axis Data
                cat = ser.getCat();
                // 获取图表的值
                val = ser.getVal();
                // strData.set
                CTStrData strData = cat.getStrRef().getStrCache();
                CTNumData numData = val.getNumRef().getNumCache();
                strData.setPtArray((CTStrVal[]) null); // unset old axis text
                numData.setPtArray((CTNumVal[]) null); // unset old values
    
                // set model
                long idx = 0;
                for (int j = 0; j < dataList.size(); j++) {
                    //判断获取的值是否为空
                    String value = "0";
                    if (new BigDecimal(dataList.get(j).get(fldNameArr.get(i + position))) != null) {
                        value = new BigDecimal(dataList.get(j).get(fldNameArr.get(i + position))).toString();
                    }
                    if (!"0".equals(value)) {
                        CTNumVal numVal = numData.addNewPt();//序列值
                        numVal.setIdx(idx);
                        numVal.setV(value);
                    }
                    CTStrVal sVal = strData.addNewPt();//序列名称
                    sVal.setIdx(idx);
                    sVal.setV(dataList.get(j).get(fldNameArr.get(0)));
                    idx++;
                }
                numData.getPtCount().setVal(idx);
                strData.getPtCount().setVal(idx);
    
    
                //赋值横坐标数据区域
                String axisDataRange = new CellRangeAddress(1, dataList.size(), 0, 0)
                        .formatAsString("Sheet1", true);
                cat.getStrRef().setF(axisDataRange);
    
                //数据区域
                String numDataRange = new CellRangeAddress(1, dataList.size(), i + position, i + position)
                        .formatAsString("Sheet1", true);
                val.getNumRef().setF(numDataRange);
    
            }
            return result;
        }
    
    
        /**
         * 刷新柱状图数据方法
         *
         * @param typeChart
         * @param serList
         * @param dataList
         * @param fldNameArr
         * @param titleArr
         * @param showtailArr
         * @param ispercentArr
         * @param position
         * @return
         */
        public static boolean refreshBarStrGraphContent(Object typeChart,
                                                        List<?> serList, List<Map<String, String>> dataList, List<String> fldNameArr, int position) {
    
            boolean result = true;
            //更新数据区域
            for (int i = 0; i < serList.size(); i++) {
                //CTSerTx tx=null;
                CTAxDataSource cat = null;
                CTNumDataSource val = null;
                CTBarSer ser = ((CTBarChart) typeChart).getSerArray(i);
                //tx= ser.getTx();
                // Category Axis Data
                cat = ser.getCat();
                // 获取图表的值
                val = ser.getVal();
                // strData.set
                CTStrData strData = cat.getStrRef().getStrCache();
                CTNumData numData = val.getNumRef().getNumCache();
                strData.setPtArray((CTStrVal[]) null); // unset old axis text
                numData.setPtArray((CTNumVal[]) null); // unset old values
    
                // set model
                long idx = 0;
                for (int j = 0; j < dataList.size(); j++) {
                    //判断获取的值是否为空
                    String value = "0";
                    if (new BigDecimal(dataList.get(j).get(fldNameArr.get(i + position))) != null) {
                        value = new BigDecimal(dataList.get(j).get(fldNameArr.get(i + position))).toString();
                    }
                    if (!"0".equals(value)) {
                        CTNumVal numVal = numData.addNewPt();//序列值
                        numVal.setIdx(idx);
                        numVal.setV(value);
                    }
                    CTStrVal sVal = strData.addNewPt();//序列名称
                    sVal.setIdx(idx);
                    sVal.setV(dataList.get(j).get(fldNameArr.get(0)));
                    idx++;
                }
                numData.getPtCount().setVal(idx);
                strData.getPtCount().setVal(idx);
    
    
                //赋值横坐标数据区域
                String axisDataRange = new CellRangeAddress(1, dataList.size(), 0, 0)
                        .formatAsString("Sheet1", true);
                cat.getStrRef().setF(axisDataRange);
    
                //数据区域
                String numDataRange = new CellRangeAddress(1, dataList.size(), i + position, i + position)
                        .formatAsString("Sheet1", true);
                val.getNumRef().setF(numDataRange);
    
            }
            return result;
        }
    
    
    
        /**
         * 刷新饼图数据方法
         *
         * @param typeChart
         * @param serList
         * @param dataList
         * @param fldNameArr
         * @param titleArr
         * @param showtailArr
         * @param ispercentArr
         * @param position
         * @return
         */
        public static boolean refreshPieStrGraphContent(Object typeChart,
                                                        List<?> serList, List<Map<String, String>> dataList, List<String> fldNameArr, int position) {
    
            boolean result = true;
            //更新数据区域
            for (int i = 0; i < serList.size(); i++) {
                //CTSerTx tx=null;
                CTAxDataSource cat = null;
                CTNumDataSource val = null;
                CTPieSer ser = ((CTPieChart) typeChart).getSerArray(i);
    
                //tx= ser.getTx();
                // Category Axis Data
                cat = ser.getCat();
                // 获取图表的值
                val = ser.getVal();
                // strData.set
                CTStrData strData = cat.getStrRef().getStrCache();
                CTNumData numData = val.getNumRef().getNumCache();
                strData.setPtArray((CTStrVal[]) null); // unset old axis text
                numData.setPtArray((CTNumVal[]) null); // unset old values
    
                // set model
                long idx = 0;
                for (int j = 0; j < dataList.size(); j++) {
                    //判断获取的值是否为空
                    String value = "0";
                    if (new BigDecimal(dataList.get(j).get(fldNameArr.get(i + position))) != null) {
                        value = new BigDecimal(dataList.get(j).get(fldNameArr.get(i + position))).toString();
                    }
                    if (!"0".equals(value)) {
                        CTNumVal numVal = numData.addNewPt();//序列值
                        numVal.setIdx(idx);
                        numVal.setV(value);
                    }
                    CTStrVal sVal = strData.addNewPt();//序列名称
                    sVal.setIdx(idx);
                    sVal.setV(dataList.get(j).get(fldNameArr.get(0)));
                    idx++;
                }
                numData.getPtCount().setVal(idx);
                strData.getPtCount().setVal(idx);
    
    
                //赋值横坐标数据区域
                String axisDataRange = new CellRangeAddress(1, dataList.size(), 0, 0)
                        .formatAsString("Sheet1", true);
                cat.getStrRef().setF(axisDataRange);
    
                //数据区域
                String numDataRange = new CellRangeAddress(1, dataList.size(), i + position, i + position)
                        .formatAsString("Sheet1", true);
                val.getNumRef().setF(numDataRange);
            }
            return result;
        }
    
    
        /**
         * 刷新内置excel数据
         *
         * @param chart
         * @param dataList
         * @param fldNameArr
         * @param titleArr
         * @param showtailArr
         * @param ispercentArr
         * @return
         */
        public static boolean refreshExcel(XWPFChart chart,
                                           List<Map<String, String>> dataList, List<String> fldNameArr, List<String> titleArr) {
            boolean result = true;
            Workbook wb = new XSSFWorkbook();
            Sheet sheet = wb.createSheet("Sheet1");
            //根据数据创建excel第一行标题行
            for (int i = 0; i < titleArr.size(); i++) {
                if (sheet.getRow(0) == null) {
                    sheet.createRow(0).createCell(i).setCellValue(titleArr.get(i) == null ? "" : titleArr.get(i));
                } else {
                    sheet.getRow(0).createCell(i).setCellValue(titleArr.get(i) == null ? "" : titleArr.get(i));
                }
            }
    
            //遍历数据行
            for (int i = 0; i < dataList.size(); i++) {
                Map<String, String> baseFormMap = dataList.get(i);//数据行
                //fldNameArr字段属性
                for (int j = 0; j < fldNameArr.size(); j++) {
                    if (sheet.getRow(i + 1) == null) {
                        if (j == 0) {
                            try {
                                sheet.createRow(i + 1).createCell(j).setCellValue(baseFormMap.get(fldNameArr.get(j)) == null ? "" : baseFormMap.get(fldNameArr.get(j)));
                            } catch (Exception e) {
                                if (baseFormMap.get(fldNameArr.get(j)) == null) {
                                    sheet.createRow(i + 1).createCell(j).setCellValue("");
                                } else {
                                    sheet.createRow(i + 1).createCell(j).setCellValue(baseFormMap.get(fldNameArr.get(j)));
                                }
                            }
                        }
                    } else {
                        BigDecimal b = new BigDecimal(baseFormMap.get(fldNameArr.get(j)));
                        double value = 0d;
                        if (b != null) {
                            value = b.doubleValue();
                        }
                        if (value == 0) {
                            sheet.getRow(i + 1).createCell(j);
                        } else {
                            sheet.getRow(i + 1).createCell(j).setCellValue(b.doubleValue());
                        }
                    }
                }
    
            }
            // 更新嵌入的workbook
            POIXMLDocumentPart xlsPart = chart.getRelations().get(0);
            OutputStream xlsOut = xlsPart.getPackagePart().getOutputStream();
    
            try {
                wb.write(xlsOut);
                xlsOut.close();
            } catch (IOException e) {
                e.printStackTrace();
                result = false;
            } finally {
                if (wb != null) {
                    try {
                        wb.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                        result = false;
                    }
                }
            }
            return result;
        }
    
    
        /**
         * 设置表格样式
         *
         * @param cell
         * @param fontName
         * @param fontSize
         * @param fontBlod
         * @param alignment
         * @param vertical
         * @param fontColor
         * @param bgColor
         * @param cellWidth
         * @param content
         */
        public  void setWordCellSelfStyle(XWPFTableCell cell, String fontName, String fontSize, int fontBlod,
                                                String alignment, String vertical, String fontColor,
                                                String bgColor, long cellWidth, String content) {
    
            //poi对字体大小设置特殊,不支持小数,但对原word字体大小做了乘2处理
            BigInteger bFontSize = new BigInteger("24");
            if (fontSize != null && !fontSize.equals("")) {
                //poi对字体大小设置特殊,不支持小数,但对原word字体大小做了乘2处理
                BigDecimal fontSizeBD = new BigDecimal(fontSize);
                fontSizeBD = bd2.multiply(fontSizeBD);
                fontSizeBD = fontSizeBD.setScale(0, BigDecimal.ROUND_HALF_UP);//这里取整
                bFontSize = new BigInteger(fontSizeBD.toString());// 字体大小
            }
            //=====获取单元格
            CTTc tc = cell.getCTTc();
            //====tcPr开始====》》》》
            CTTcPr tcPr = tc.getTcPr();//获取单元格里的<w:tcPr>
            if (tcPr == null) {//没有<w:tcPr>,创建
                tcPr = tc.addNewTcPr();
            }
    
            //  --vjc开始-->>
            CTVerticalJc vjc = tcPr.getVAlign();//获取<w:tcPr>  的<w:vAlign w:val="center"/>
            if (vjc == null) {//没有<w:w:vAlign/>,创建
                vjc = tcPr.addNewVAlign();
            }
            //设置单元格对齐方式
            vjc.setVal(vertical.equals("top") ? STVerticalJc.TOP : vertical.equals("bottom") ? STVerticalJc.BOTTOM : STVerticalJc.CENTER); //垂直对齐
    
            CTShd shd = tcPr.getShd();//获取<w:tcPr>里的<w:shd w:val="clear" w:color="auto" w:fill="C00000"/>
            if (shd == null) {//没有<w:shd>,创建
                shd = tcPr.addNewShd();
            }
            // 设置背景颜色
            shd.setFill(bgColor.substring(1));
            //《《《《====tcPr结束====
    
            //====p开始====》》》》
            CTP p = tc.getPList().get(0);//获取单元格里的<w:p w:rsidR="00C36068" w:rsidRPr="00B705A0" w:rsidRDefault="00C36068" w:rsidP="00C36068">
    
            //---ppr开始--->>>
            CTPPr ppr = p.getPPr();//获取<w:p>里的<w:pPr>
            if (ppr == null) {//没有<w:pPr>,创建
                ppr = p.addNewPPr();
            }
            //  --jc开始-->>
            CTJc jc = ppr.getJc();//获取<w:pPr>里的<w:jc w:val="left"/>
            if (jc == null) {//没有<w:jc/>,创建
                jc = ppr.addNewJc();
            }
            //设置单元格对齐方式
            jc.setVal(alignment.equals("left") ? STJc.LEFT : alignment.equals("right") ? STJc.RIGHT : STJc.CENTER); //水平对齐
            //  <<--jc结束--
            //  --pRpr开始-->>
            CTParaRPr pRpr = ppr.getRPr(); //获取<w:pPr>里的<w:rPr>
            if (pRpr == null) {//没有<w:rPr>,创建
                pRpr = ppr.addNewRPr();
            }
            CTFonts pfont = pRpr.getRFonts();//获取<w:rPr>里的<w:rFonts w:ascii="宋体" w:eastAsia="宋体" w:hAnsi="宋体"/>
            if (pfont == null) {//没有<w:rPr>,创建
                pfont = pRpr.addNewRFonts();
            }
            //设置字体
            pfont.setAscii(fontName);
            pfont.setEastAsia(fontName);
            pfont.setHAnsi(fontName);
    
            CTOnOff pb = pRpr.getB();//获取<w:rPr>里的<w:b/>
            if (pb == null) {//没有<w:b/>,创建
                pb = pRpr.addNewB();
            }
            //设置字体是否加粗
            pb.setVal(fontBlod == 1 ? STOnOff.ON : STOnOff.OFF);
    
            CTHpsMeasure psz = pRpr.getSz();//获取<w:rPr>里的<w:sz w:val="32"/>
            if (psz == null) {//没有<w:sz w:val="32"/>,创建
                psz = pRpr.addNewSz();
            }
            // 设置单元格字体大小
            psz.setVal(bFontSize);
            CTHpsMeasure pszCs = pRpr.getSzCs();//获取<w:rPr>里的<w:szCs w:val="32"/>
            if (pszCs == null) {//没有<w:szCs w:val="32"/>,创建
                pszCs = pRpr.addNewSzCs();
            }
            // 设置单元格字体大小
            pszCs.setVal(bFontSize);
            //  <<--pRpr结束--
            //<<<---ppr结束---
    
            //---r开始--->>>
            List<CTR> rlist = p.getRList(); //获取<w:p>里的<w:r w:rsidRPr="00B705A0">
            CTR r = null;
            if (rlist != null && rlist.size() > 0) {//获取第一个<w:r>
                r = rlist.get(0);
            } else {//没有<w:r>,创建
                r = p.addNewR();
            }
            //--rpr开始-->>
            CTRPr rpr = r.getRPr();//获取<w:r w:rsidRPr="00B705A0">里的<w:rPr>
            if (rpr == null) {//没有<w:rPr>,创建
                rpr = r.addNewRPr();
            }
            //->-
            CTFonts font = rpr.getRFonts();//获取<w:rPr>里的<w:rFonts w:ascii="宋体" w:eastAsia="宋体" w:hAnsi="宋体" w:hint="eastAsia"/>
            if (font == null) {//没有<w:rFonts>,创建
                font = rpr.addNewRFonts();
            }
            //设置字体
            font.setAscii(fontName);
            font.setEastAsia(fontName);
            font.setHAnsi(fontName);
    
            CTOnOff b = rpr.getB();//获取<w:rPr>里的<w:b/>
            if (b == null) {//没有<w:b/>,创建
                b = rpr.addNewB();
            }
            //设置字体是否加粗
            b.setVal(fontBlod == 1 ? STOnOff.ON : STOnOff.OFF);
            CTColor color = rpr.getColor();//获取<w:rPr>里的<w:color w:val="FFFFFF" w:themeColor="background1"/>
            if (color == null) {//没有<w:color>,创建
                color = rpr.addNewColor();
            }
            // 设置字体颜色
            if (content.contains("↓")) {
                color.setVal("43CD80");
            } else if (content.contains("↑")) {
                color.setVal("943634");
            } else {
                color.setVal(fontColor.substring(1));
            }
            CTHpsMeasure sz = rpr.getSz();
            if (sz == null) {
                sz = rpr.addNewSz();
            }
            sz.setVal(bFontSize);
            CTHpsMeasure szCs = rpr.getSzCs();
            if (szCs == null) {
                szCs = rpr.addNewSz();
            }
            szCs.setVal(bFontSize);
            //-<-
            //<<--rpr结束--
            List<CTText> tlist = r.getTList();
            CTText t = null;
            if (tlist != null && tlist.size() > 0) {//获取第一个<w:r>
                t = tlist.get(0);
            } else {//没有<w:r>,创建
                t = r.addNewT();
            }
            t.setStringValue(content);
            //<<<---r结束---
        }
    
    }
    View Code

    4.2 调用类

    package com.censoft.app.wordreport;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import org.apache.poi.ooxml.POIXMLDocumentPart;
    import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
    import org.apache.poi.xwpf.usermodel.XWPFChart;
    import org.apache.poi.xwpf.usermodel.XWPFDocument;
    import org.apache.poi.xwpf.usermodel.XWPFParagraph;
    import org.apache.poi.xwpf.usermodel.XWPFRun;
    import org.apache.poi.xwpf.usermodel.XWPFTable;
    import org.apache.poi.xwpf.usermodel.XWPFTableCell;
    import org.apache.poi.xwpf.usermodel.XWPFTableRow;
    import org.apache.xmlbeans.XmlCursor;
    import org.springframework.util.StringUtils;
    
    import com.censoft.app.wordreport.util.PoiWordTools;
    
    public class PoiJdWordTable {
    
        public static void main(String[] args) throws Exception {
        
    
        String[] nds = new String[]{"2018年","2019年"};
        String[] qq = new String[]{"全区"};
        String jidus[] = new String[]{"2018年第3季度","2018年第4季度","2019年第1季度","2019年第2季度"};
        String[] yuedus = new String[]{"2018年07月","2018年08月","2018年09月","2018年10月","2018年11月","2018年12月","2019年01月","2019年02月","2019年03月","2019年04月","2019年05月","2019年06月"};
            String[] jds = new String[]{"万寿路街道",
                "上地街道",
                "东升镇",
                "中关村街道",
                "八里庄街道",
                "北下关街道",
                "北太平庄街道",
                "四季青镇",
                "学院路街道",
                "曙光街道",
                "永定路街道",
                "海淀街道",
                "海淀镇",
                "清华园街道",
                "清河街道",
                "温泉镇",
                "燕园街道",
                "甘家口街道",
                "田村路街道",
                "紫竹院街道",
                "羊坊店街道",
                "花园路街道",
                "苏家坨镇",
                "西三旗街道",
                "西北旺镇",
                "青龙桥街道",
                "香山街道",
                "马连洼街道"};
            
            for(int i=0;i<jds.length;i++){
                 for (int j = 0; j < nds.length; j++) {
                String returnurl = "D:/word/封面/生成/街道(年度)/"+nds[j].replace("年", "")+jds[i]+"楼宇报告.docx"; // 结果文件
                    final String templateurl = "D:/word/封面/年度报告封面.docx"; // 模板文件
                    Map<String, String> textMap = new HashMap<String,String>();
                    textMap.put("key1", jds[i]);
                    textMap.put("key2", nds[j]);
                    method(templateurl,returnurl,textMap);
            }
               /* for (int j = 0; j < jidus.length; j++) {
                String returnurl = "D:/word/封面/生成/街道(季度)/"+jds[i]+"楼宇"+jidus[j]+"报告.docx"; // 结果文件
                    final String templateurl = "D:/word/封面/季度报告封面.docx"; // 模板文件
                    Map<String, String> textMap = new HashMap<String,String>();
                    textMap.put("key1", jds[i]);
                    textMap.put("key2", jidus[j]);
                    method(templateurl,returnurl,textMap);
            }
                for (int j = 0; j < yuedus.length; j++) {
                String returnurl = "D:/word/封面/生成/街道(月度)/"+jds[i]+yuedus[j]+"报告.docx"; // 结果文件
                    final String templateurl = "D:/word/封面/月度报告封面.docx"; // 模板文件
                    Map<String, String> textMap = new HashMap<String,String>();
                    textMap.put("key1", jds[i]);
                    textMap.put("key2", yuedus[j]);
                    method(templateurl,returnurl,textMap);
            }*/
            }
          /*  for(int i=0;i<qq.length;i++){
                for (int j = 0; j < nds.length; j++) {
                String returnurl = "D:/word/封面/生成/全区(年度)/"+nds[j]+qq[i]+"楼宇年度报告.docx"; // 结果文件
                    final String templateurl = "D:/word/封面/年度报告封面.docx"; // 模板文件
                    Map<String, String> textMap = new HashMap<String,String>();
                    textMap.put("key1", qq[i]);
                    textMap.put("key2", nds[j]);
                    method(templateurl,returnurl,textMap);
            }
                for (int j = 0; j < jidus.length; j++) {
                String returnurl = "D:/word/封面/生成/全区(季度)/"+qq[i]+"楼宇"+jidus[j]+"报告.docx"; // 结果文件
                    final String templateurl = "D:/word/封面/季度报告封面.docx"; // 模板文件
                    Map<String, String> textMap = new HashMap<String,String>();
                    textMap.put("key1", qq[i]);
                    textMap.put("key2", jidus[j]);
                    method(templateurl,returnurl,textMap);
            }
                for (int j = 0; j < yuedus.length; j++) {
                String returnurl = "D:/word/封面/生成/全区(月度)/"+qq[i]+yuedus[j]+"报告.docx"; // 结果文件
                    final String templateurl = "D:/word/封面/月度报告封面.docx"; // 模板文件
                    Map<String, String> textMap = new HashMap<String,String>();
                    textMap.put("key1", qq[i]);
                    textMap.put("key2", yuedus[j]);
                    method(templateurl,returnurl,textMap);
            }
            }*/
    
        
        }
        
        public static void method(String templateurl,String returnurl,Map<String, String> textMap) throws IOException, InvalidFormatException{
        
        InputStream is = new FileInputStream(new File(templateurl));
            XWPFDocument doc = new XWPFDocument(is);
    
            // 替换word模板数据
            replaceFm(doc,textMap);
    
            // 保存结果文件
            try {
                File file = new File(returnurl);
                if (file.exists()) {
                file.delete();
                }
                FileOutputStream fos = new FileOutputStream(returnurl);
                doc.write(fos);
                fos.close();
                doc.close();
                is.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        
        }
        
        public static void replaceFm(XWPFDocument doc,Map<String, String> textMap)
            throws InvalidFormatException, IOException {
         doParagraphs(doc,textMap); // 处理段落文字数据,包括文字
         System.out.println("文本替换完成");
        }
    
        /**
         * @Description: 替换段落和表格中
         */
        public static void replaceAll(XWPFDocument doc,List<List<Map<String, String>>> listtable,List<List<Map<String, String>>> listchart,Map<String, String> textMap)
            throws InvalidFormatException, IOException {
         doParagraphs(doc,textMap); // 处理段落文字数据,包括文字
         System.out.println("文本替换完成");
         doTables(doc, listtable); //表格
         System.out.println("表格替换完成");
         doCharts(doc,listchart); // 处理图表数据,柱状图、折线图、饼图啊之类的
        }
        
        public static void replaceFgs(XWPFDocument doc,List<List<Map<String, String>>> listtable,List<List<Map<String, String>>> listchart,Map<String, String> textMap)
            throws InvalidFormatException, IOException {
         doParagraphs(doc,textMap); // 处理段落文字数据,包括文字
         System.out.println("文本替换完成");
         doTables(doc, listtable); //表格
         System.out.println("表格替换完成");
         doChartsFgs(doc,listchart); // 处理图表数据,柱状图、折线图、饼图啊之类的
        }
    
        /**
         * 处理table
         */
        public static void doTables(XWPFDocument doc,List<List<Map<String, String>>> list)
            throws InvalidFormatException, IOException {
        List<XWPFTable> tables = doc.getTables();
        for (int i = 0; i < tables.size(); i++) {
            XWPFTable table = tables.get(i);
            // 获取表头
            XWPFTableRow header = table.getRow(0);
    
            if (list.size() > i) {
            for (int h = 1; h <= list.get(i).size(); h++) {
                table.createRow();
            }
            List<XWPFTableRow> rows = table.getRows();
            /*for (int j = 0; j < list.get(i).size(); j++) {
                // XWPFTableRow row = table.getRow(i+1);
                Map<String, String> map = list.get(i).get(j);
                for (int k = 0; k < header.getTableCells().size(); k++) {
                String text = String.valueOf(map.get("key" + String.valueOf(k + 1)));
                if(text.endsWith(".0")){
                    text=text.replace(".0", "");
                }
                if("null".equals(text)){
                    text="";
                }
                
                rows.get(j + 1).getTableCells().get(k).setText(text);
                }
            }*/
            for (int j = 0; j < list.get(i).size(); j++) {
                // XWPFTableRow row = table.getRow(i+1);
                List<XWPFTableCell> cellList = rows.get(j + 1).getTableCells();
                Map<String, String> map = list.get(i).get(j);
                for (int k = 0; k < header.getTableCells().size(); k++) {
                    String text = String.valueOf(map.get("key" + String.valueOf(k + 1)));
                    if(text.endsWith(".0")){
                        text=text.replace(".0", "");
                    }
                    if("null".equals(text)){
                        text="";
                    }
                    XWPFTableCell cell = cellList.get(k);
                    new PoiWordTools().setWordCellSelfStyle(cell, "微软雅黑", "11", 0, "left", "m", "#000000", "#FFFFFF", 10, text);
                }
            }
            }
    
        }
    
        }
    
        /**
         * 处理段落文字
         * 
         * @param doc
         * @throws InvalidFormatException
         * @throws FileNotFoundException
         * @throws IOException
         */
        public static void doParagraphs(XWPFDocument doc,
            Map<String, String> textMap) throws InvalidFormatException,
            IOException {
        /* textMap.put("fgs", "第一房管所"); */
        /** ----------------------------处理段落------------------------------------ **/
        List<XWPFParagraph> paragraphList = doc.getParagraphs();
        if (paragraphList != null && paragraphList.size() > 0) {
            for (XWPFParagraph paragraph : paragraphList) {
            List<XWPFRun> runs = paragraph.getRuns();
            for (XWPFRun run : runs) {
                String text = run.getText(0);
                if (text != null) {
                // 替换文本信息
                String key = text.replaceAll("\{\{", "").replaceAll("}}", "");
                if (!StringUtils.isEmpty(textMap.get(key))) {
                    run.setText(textMap.get(key), 0);
                }
                }
            }
            }
        }
        }
    
        public static void doCharts(XWPFDocument doc,
            List<List<Map<String, String>>> list) throws FileNotFoundException {
        /** ----------------------------处理图表------------------------------------ **/
        String[] params = {"title","数量(幢)","建筑面积(万平方米)"};
        String[] params2 = {"title","套数","建筑面积(万平方米)"};
        String[] params3 = {"title","建筑面积(万平方米)"};
        String[] params4 = {"title","数量"};
        String[] params5 = {"title","套数占比","建筑面积占比"};
        
        doChartsOne(doc,list.get(0),0,params);
        System.out.println("图1替换完成");
        doChartsTwo(doc,list.get(1),1,params3);
        System.out.println("图2替换完成");
        doChartsOne(doc,list.get(2),2,params);
        System.out.println("图3替换完成");
        doChartsOne(doc,list.get(3),3,params);
        System.out.println("图4替换完成");
        doChartsOne(doc,list.get(4),4,params);
        System.out.println("图5替换完成");
        doChartsOne(doc,list.get(5),5,params);
        System.out.println("图6替换完成");
        doChartsOne(doc,list.get(6),6,params);
        System.out.println("图7替换完成");
        doChartsOne(doc,list.get(7),7,params);
        System.out.println("图8替换完成");
        doChartsOne(doc,list.get(8),8,params2);
        System.out.println("图9替换完成");
        doChartsThree(doc,list.get(9),9,params5);
        System.out.println("图10替换完成");
        doChartsOne(doc,list.get(10),10,params);
        System.out.println("图11替换完成");
        doChartsOne(doc,list.get(11),11,params);
        System.out.println("图12替换完成");
        doChartsOne(doc,list.get(12),12,params);
        System.out.println("图13替换完成");
        doChartsTwo(doc,list.get(13),13,params4);
        System.out.println("图14替换完成");
        }
        
        public static void doChartsFgs(XWPFDocument doc,
            List<List<Map<String, String>>> list) throws FileNotFoundException {
        /** ----------------------------处理图表------------------------------------ **/
        String[] params = {"title","数量(幢)","建筑面积(万平方米)"};
        String[] params2 = {"title","套数","建筑面积(万平方米)"};
        String[] params3 = {"title","建筑面积(万平方米)"};
        String[] params4 = {"title","数量"};
        String[] params5 = {"title","数量(幢)","占街镇比重"};
        String[] params6 = {"title","完成月度更新楼宇数量(幢)"};
        doChartsOne(doc,list.get(0),0,params);
        System.out.println("图1替换完成");
        doChartsTwo(doc,list.get(1),1,params4);
        System.out.println("图2替换完成");
        doChartsTwo(doc,list.get(2),2,params3);
        System.out.println("图3替换完成");
        doChartsOne(doc,list.get(3),3,params);
        System.out.println("图4替换完成");
        doChartsOne(doc,list.get(4),4,params5);
        System.out.println("图5替换完成");
        doChartsOne(doc,list.get(5),5,params);
        System.out.println("图6替换完成");
        doChartsOne(doc,list.get(6),6,params);
        System.out.println("图7替换完成");
        doChartsThreeSingle(doc,list.get(7),7,params3);
        System.out.println("图8替换完成");
        doChartsOne(doc,list.get(8),8,params);
        System.out.println("图9替换完成");
        doChartsOne(doc,list.get(9),9,params5);
        System.out.println("图10替换完成");
        doChartsOne(doc,list.get(10),10,params);
        System.out.println("图11替换完成");
        doChartsOne(doc,list.get(11),11,params2);
        System.out.println("图12替换完成");
        doChartsOne(doc,list.get(12),12,params2);
        System.out.println("图13替换完成");
        doChartsOne(doc,list.get(13),13,params5);
        System.out.println("图14替换完成");
        doChartsThreeSingle(doc,list.get(14),14,params3);
        System.out.println("图15替换完成");
        doChartsThreeSingle(doc,list.get(15),15,params6);
        System.out.println("图16替换完成");
        }
    
        /**
         * 处理图表 
         * 柱图折线图组合图
         * @param doc
         * @throws FileNotFoundException
         */
        public static void doChartsOne(XWPFDocument doc,List<Map<String, String>> listBasicData,int i,String[] params)
            throws FileNotFoundException {
        /** ----------------------------处理图表------------------------------------ **/
    
        // 数据准备
        List<String> titleArr = new ArrayList<String>();// 标题
        titleArr.add(params[0]);
        titleArr.add(params[1]);
        titleArr.add(params[2]);
    
        List<String> fldNameArr = new ArrayList<String>();// 字段名
        fldNameArr.add("item1");
        fldNameArr.add("item2");
        fldNameArr.add("item3");
    
        // 数据集合
        List<Map<String, String>> listItemsByType = new ArrayList<Map<String, String>>();
    
        for (Map<String, String> map : listBasicData) {
            Map<String, String> base = new HashMap<String, String>();
            base.put("item1", map.get(params[0]));
            base.put("item2", String.valueOf(map.get(params[1])));
            base.put("item3", String.valueOf(map.get(params[2])));
            if(base.get("item2").equals("null")){
            base.put("item2", "0");
            }
            if(base.get("item3").equals("null")){
            base.put("item3", "0");
            }
            listItemsByType.add(base);
        }
        
        // 获取word模板中的所有图表元素,用数组存放
        List<POIXMLDocumentPart> chartsList = new ArrayList<POIXMLDocumentPart>();
        // 动态刷新图表
        List<POIXMLDocumentPart> relations = doc.getRelations();
        for (POIXMLDocumentPart poixmlDocumentPart : relations) {
            if (poixmlDocumentPart instanceof XWPFChart) { // 如果是图表元素
            chartsList.add(poixmlDocumentPart);
            }
        }
    
        // 下标5的图表-组合图(柱状图+折线图)
        POIXMLDocumentPart poixmlDocumentPart = chartsList.get(i);
        new PoiWordTools().replaceCombinationCharts(poixmlDocumentPart,titleArr, fldNameArr, listItemsByType);
        
        }
    
        /**
         * 处理图表 饼图
         * 
         * @param doc
         * @throws FileNotFoundException
         */
        public static void doChartsTwo(XWPFDocument doc,List<Map<String, String>> listBasicData,int i,String[] params)
            throws FileNotFoundException {
        /** ----------------------------处理图表------------------------------------ **/
        // 数据准备
        List<String> titleArr = new ArrayList<String>();// 标题
        titleArr.add(params[0]);
        titleArr.add(params[1]);
        List<String> fldNameArr = new ArrayList<String>();// 字段名
        fldNameArr.add("item1");
        fldNameArr.add("item2");
    
        // 数据集合
        List<Map<String, String>> listItemsByType = new ArrayList<Map<String, String>>();
    
        for (Map<String, String> map : listBasicData) {
            Map<String, String> base = new HashMap<String, String>();
            base.put("item1", map.get("title"));
            base.put("item2", String.valueOf(map.get("value")));
            if(base.get("item2").equals("null")){
            base.put("item2", "0");
            }
            listItemsByType.add(base);
        }
    
        // 获取word模板中的所有图表元素,用数组存放
        List<POIXMLDocumentPart> chartsList = new ArrayList<POIXMLDocumentPart>();
        // 动态刷新图表
        List<POIXMLDocumentPart> relations = doc.getRelations();
        for (POIXMLDocumentPart poixmlDocumentPart : relations) {
            if (poixmlDocumentPart instanceof XWPFChart) { // 如果是图表元素
            chartsList.add(poixmlDocumentPart);
            }
        }
        // 饼图
        POIXMLDocumentPart poixmlDocumentPart4 = chartsList.get(i);
        new PoiWordTools().replacePieCharts(poixmlDocumentPart4, titleArr,
            fldNameArr, listItemsByType);
        }
    
        /**
         * 处理图表 
         * 柱图
         * @param doc
         * @throws FileNotFoundException
         */
        public static void doChartsThree(XWPFDocument doc,List<Map<String, String>> listBasicData,int i,String[] params)
            throws FileNotFoundException {
        /** ----------------------------处理图表------------------------------------ **/
        // 数据准备
        List<String> titleArr = new ArrayList<String>();// 标题
        titleArr.add(params[0]);
        titleArr.add(params[1]);
        titleArr.add(params[2]);
    
        List<String> fldNameArr = new ArrayList<String>();// 字段名
        fldNameArr.add("item1");
        fldNameArr.add("item2");
        fldNameArr.add("item3");
    
        // 数据集合
        List<Map<String, String>> listItemsByType = new ArrayList<Map<String, String>>();
    
        for (Map<String, String> map : listBasicData) {
            Map<String, String> base = new HashMap<String, String>();
            base.put("item1", map.get(params[0]));
            base.put("item2", String.valueOf(map.get(params[1])));
            base.put("item3", String.valueOf(map.get(params[2])));
            listItemsByType.add(base);
            if(base.get("item2").equals("null")){
            base.put("item2", "0");
            }
            if(base.get("item3").equals("null")){
            base.put("item3", "0");
            }
        }
        // 获取word模板中的所有图表元素,用数组存放
        List<POIXMLDocumentPart> chartsList = new ArrayList<POIXMLDocumentPart>();
        // 动态刷新图表
        List<POIXMLDocumentPart> relations = doc.getRelations();
        for (POIXMLDocumentPart poixmlDocumentPart : relations) {
            if (poixmlDocumentPart instanceof XWPFChart) { // 如果是图表元素
            chartsList.add(poixmlDocumentPart);
            }
        }
        
        POIXMLDocumentPart poixmlDocumentPart = chartsList.get(i);
        new PoiWordTools().replaceBarCharts(poixmlDocumentPart, titleArr, fldNameArr, listItemsByType);
        }
        
        /**
         * 单柱图
         * @param doc
         * @param listBasicData
         * @param i
         * @param params
         * @throws FileNotFoundException
         */
        public static void doChartsThreeSingle(XWPFDocument doc,List<Map<String, String>> listBasicData,int i,String[] params)
            throws FileNotFoundException {
        /** ----------------------------处理图表------------------------------------ **/
        // 数据准备
        List<String> titleArr = new ArrayList<String>();// 标题
        titleArr.add(params[0]);
        titleArr.add(params[1]);
    
        List<String> fldNameArr = new ArrayList<String>();// 字段名
        fldNameArr.add("item1");
        fldNameArr.add("item2");
    
        // 数据集合
        List<Map<String, String>> listItemsByType = new ArrayList<Map<String, String>>();
    
        for (Map<String, String> map : listBasicData) {
            Map<String, String> base = new HashMap<String, String>();
            base.put("item1", map.get(params[0]));
            base.put("item2", String.valueOf(map.get(params[1])));
            listItemsByType.add(base);
            if(base.get("item2").equals("null")){
            base.put("item2", "0");
            }
        }
        // 获取word模板中的所有图表元素,用数组存放
        List<POIXMLDocumentPart> chartsList = new ArrayList<POIXMLDocumentPart>();
        // 动态刷新图表
        List<POIXMLDocumentPart> relations = doc.getRelations();
        for (POIXMLDocumentPart poixmlDocumentPart : relations) {
            if (poixmlDocumentPart instanceof XWPFChart) { // 如果是图表元素
            chartsList.add(poixmlDocumentPart);
            }
        }
        
        POIXMLDocumentPart poixmlDocumentPart = chartsList.get(i);
        new PoiWordTools().replaceBarCharts(poixmlDocumentPart, titleArr, fldNameArr, listItemsByType);
        }
    
    }
    View Code
  • 相关阅读:
    切割图像(一)概要
    无锁队列--基于linuxkfifo实现
    c++ virturn function -- 虚函数
    c friend -- 友元
    c++ anonymous union,struct -- 匿名联合体和机构体
    c++ anonymous namespace -- 匿名空间
    c++ inheritance -- 继承
    c++ 类名和enum时重复时要在类名前加class::
    c vs c++ in strcut and class
    C++ operator overload -- 操作符重载
  • 原文地址:https://www.cnblogs.com/winddogg/p/11933746.html
Copyright © 2011-2022 走看看