一、需求说明

定期生成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结束---
} }

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

读取word模板,填充数据后导出的更多相关文章

  1. POI3.10读取Excel模板填充数据后生成新的Excel文件

    private final DecimalFormat df = new DecimalFormat("#0.00"); public void test(){ String fi ...

  2. 读取excel模板填充数据 并合并相同文本单元格

    try             { string OutFileName = "北京市国控企业污染源废气在线比对监测数据审核表" + DateTime.Now.ToString(& ...

  3. Freemarker取list集合中数据(将模板填充数据后写到客户端HTML)

    1.模板写法: <html> <head> <title>freemarker测试</title> </head> <body> ...

  4. 用NPOI从DataTable到Excel,向Excel模板填充数据

    DataTable---->Excel,填充数据 private IWorkbook workbook = null; private ISheet sheet = null; private ...

  5. MiniWord .NET Word模板引擎,藉由Word模板和数据简单、快速生成文件。

    Github / Gitee QQ群(1群) : 813100564 / QQ群(2群) : 579033769 介绍 MiniWord .NET Word模板引擎,藉由Word模板和数据简单.快速生 ...

  6. C#读取Word模板替换相应的字符串(标签)生成新的Word

    在平常工作中,生成word的方式主要是C#读取html的模板文件处理之后保存为.doc文件,这样的好处是方便,快捷,能满足大部分的需求.不过有些特殊的需求并不能满足,如要生成的Word为一个表格,只是 ...

  7. java poi 从服务器下载模板写入数据再导出

    最近写了一个,Excel 的 写入和导出.   需求是这样的.   在新建合同的时候,会有导出合同的数据,    导出的模板是固定的,,需要在模板里面写入合同的信息. first   :  下载模板 ...

  8. Python 读取word中表格数据、读取word修改并保存、替换word中词汇、读取word中每段内容,读取一段话中相同样式内容,理解Document中run

    from docx import Document path = r'D:\pywork\12' # word信息表所在文件夹 w = Document(path + '/' + 'word信息表.d ...

  9. 无插件,无com组件,利用EXCEL、WORD模板做数据导出(一)

    本次随笔主要讲述着工作中是如何解决数据导出的,对于数据导出到excel在日常工作中大家还是比较常用的,那导出到word呢,改如何处理呢,简单的页面导出问题应该不大,但是如果是标准的公文导出呢,要保证其 ...

随机推荐

  1. vSphere 计算vMotion的迁移原理

    1. 计算vMotion 的应用场景 1). 计划内停机维护 2). 提高资源的利用率 2. 计算vMotion 需求: 1).共享存储 vMotion需要解决的核心问题就是:将VMs的内存从源ESX ...

  2. 卸载重装ngin的问题解决方案

    1,卸载nginx不保留配置文件 $ sudo apt-get --purge remove nginx 2,卸载自动安装且不再需要的依赖包 $ sudo apt-get autoremove 3,卸 ...

  3. java api 远程连接 hdfs

    IDEA中新建Maven工程,添加POM依赖, 在IDE的提示中, 点击 Import Changes 等待自动下载完成相关的依赖包. <?xml version="1.0" ...

  4. Redis详解(八)——企业级解决方案

    Redis详解(八)--企业级解决方案 缓存预热 缓存预热就是系统上线后,提前将相关的缓存数据直接加载到缓存系统.避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题!用户直接查询事先被预热的缓 ...

  5. python手动实现深拷贝

    深拷贝是将对象全拷贝,包括嵌套对象 def deepcopy(cls): if isinstance(cls, dict): dct = {} for k, v in cls.items(): dct ...

  6. Codeforces Forethought Future Cup Elimination Round 选做

    1146C Tree Diameter 题意 交互题.有一棵 \(n(n\le 100)\) 个点的树,你可以进行不超过 \(9\) 次询问,每次询问两个点集中两个不在同一点集的点的最大距离.求树的直 ...

  7. Arrays类常用方法

    Arrays类 3.1 概述 java.util.Arrays 此类包含用来操作数组的各种方法,比如排序和搜索等.其所有方法均为静态方法. 3.2 操作数组的方法 1.将参数数组变成字符串 publi ...

  8. NO10 查看Linux操作系统-版本-内核-Linux分区

    ·看Linux系统: [root@localhost ~]# uname -m  (看操作系统)x86_64[root@localhost ~]# uname -a   (看操作系统)Linux lo ...

  9. windows下修改pip安装源的办法

    之前的随笔里有写过关于Mac OS和Linux的,现在需要用到Windows的系统, 修改方法:路径----> C:\Users\用户名\AppData\Roaming,在Roaming文件夹下 ...

  10. ruby资料

    源码样例 链接: https://pan.baidu.com/s/1mh55bFM 密码: 6cjy 初级代码 链接: https://pan.baidu.com/s/1hschnUW 密码: 8n1 ...