一、需求说明
定期生成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 工具类
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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结束--- } }
4.2 调用类
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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); } }