读取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结束---
} }
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模板,填充数据后导出的更多相关文章
- POI3.10读取Excel模板填充数据后生成新的Excel文件
private final DecimalFormat df = new DecimalFormat("#0.00"); public void test(){ String fi ...
- 读取excel模板填充数据 并合并相同文本单元格
try { string OutFileName = "北京市国控企业污染源废气在线比对监测数据审核表" + DateTime.Now.ToString(& ...
- Freemarker取list集合中数据(将模板填充数据后写到客户端HTML)
1.模板写法: <html> <head> <title>freemarker测试</title> </head> <body> ...
- 用NPOI从DataTable到Excel,向Excel模板填充数据
DataTable---->Excel,填充数据 private IWorkbook workbook = null; private ISheet sheet = null; private ...
- MiniWord .NET Word模板引擎,藉由Word模板和数据简单、快速生成文件。
Github / Gitee QQ群(1群) : 813100564 / QQ群(2群) : 579033769 介绍 MiniWord .NET Word模板引擎,藉由Word模板和数据简单.快速生 ...
- C#读取Word模板替换相应的字符串(标签)生成新的Word
在平常工作中,生成word的方式主要是C#读取html的模板文件处理之后保存为.doc文件,这样的好处是方便,快捷,能满足大部分的需求.不过有些特殊的需求并不能满足,如要生成的Word为一个表格,只是 ...
- java poi 从服务器下载模板写入数据再导出
最近写了一个,Excel 的 写入和导出. 需求是这样的. 在新建合同的时候,会有导出合同的数据, 导出的模板是固定的,,需要在模板里面写入合同的信息. first : 下载模板 ...
- Python 读取word中表格数据、读取word修改并保存、替换word中词汇、读取word中每段内容,读取一段话中相同样式内容,理解Document中run
from docx import Document path = r'D:\pywork\12' # word信息表所在文件夹 w = Document(path + '/' + 'word信息表.d ...
- 无插件,无com组件,利用EXCEL、WORD模板做数据导出(一)
本次随笔主要讲述着工作中是如何解决数据导出的,对于数据导出到excel在日常工作中大家还是比较常用的,那导出到word呢,改如何处理呢,简单的页面导出问题应该不大,但是如果是标准的公文导出呢,要保证其 ...
随机推荐
- C++面试常见问题——11重载、覆盖、隐藏
重载.覆盖.隐藏 重载 在同一类定义的成员函数中,参数不同的同名函数为重载关系.重载与虚函数无关. class A{ private: int x; public: void fun(int); // ...
- Day4 - H - Following Orders POJ - 1270
Order is an important concept in mathematics and in computer science. For example, Zorn's Lemma stat ...
- 一、Vue环境搭建及基础用法
一.项目初始化及安装 官网:https://cn.vuejs.org/ 1.1安装及运行项目步骤 1.安装vue-cli(-g=-global) npm install -g vue-cli cnpm ...
- DevOps - 与敏捷方法区别
章节 DevOps – 为什么 DevOps – 与传统方式区别 DevOps – 优势 DevOps – 不适用 DevOps – 生命周期 DevOps – 与敏捷方法区别 DevOps – 实施 ...
- POJ 2309:BST lowbit
BST Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9140 Accepted: 5580 Description C ...
- 【Linux】linux内核学习
linux内核获取 官网: https://www.kernel.org/ Linux操作系统的核心是模块化,可以使用lsmod命令查看内核模块,下面展示已载入系统的模块: [root@172.16. ...
- LocalDateTime整合到SpringBoot + MyBatis中
啥也不说先贴两个代码: 一:MVC层配置 @Configuration public class JacksonConfig { /** 默认日期时间格式 */ public static final ...
- 精简总结redis/rabbitmq/zookeeper在linux centos7上的安装
因为本博主之前已经写过了相关的一些安装及集群,可以参考前面的记录,但是由于博最近更换了VM14和centos7,为了适应这些环境,所以后续会逐渐重新搭建相关环境,并对之前的安装思路进一步精简梳理,以期 ...
- mysql IF-IFNULL和IF-ISNULL同样逻辑的运行差别
首先,目标记录是存在的 SELECT * FROM d_device_user_bind dub WHERE dub.`uid`='222222222221' 其次, SELECT dub.uid,d ...
- WIN10打开资源管理器显示该文件没有与之关联的程序来执行该操作.请安装应用,请在“默认应用设置”..关联 —— 解决方案
win+R,输入regedit,分别在HKEY_CLASSES_ROOT\piffileHKEY_CLASSES_ROOT\InternetShortcutHKEY_CLASSES_ROOT\lnkf ...