package com.turing.report.controller;
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.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.List;
import java.util.Map;
/**
* poi生成word的工具类
*/
@Component
public class PoiWordTools {
private static final BigDecimal bd2 = new BigDecimal("2");
/**
* 调用替换柱状图数据
*/
public static void replaceBarCharts(POIXMLDocumentPart poixmlDocumentPart,
List titleArr, List fldNameArr, List> listItemsByType) {
XWPFChart chart = (XWPFChart) poixmlDocumentPart;
chart.getCTChart();
//根据属性第一列名称切换数据类型
CTChart ctChart = chart.getCTChart();
CTPlotArea plotArea = ctChart.getPlotArea();
CTBarChart barChart = plotArea.getBarChartArray(0);
List BarSerList = barChart.getSerList(); // 获取柱状图单位
//刷新内置excel数据
refreshExcel(chart, listItemsByType, fldNameArr, titleArr);
//刷新页面显示数据
refreshBarStrGraphContent(barChart, BarSerList, listItemsByType, fldNameArr, 1);
}
/**
* 调用替换折线图数据
*/
public static void replaceLineCharts(POIXMLDocumentPart poixmlDocumentPart,
List titleArr, List fldNameArr, List> listItemsByType) {
XWPFChart chart = (XWPFChart) poixmlDocumentPart;
chart.getCTChart();
//根据属性第一列名称切换数据类型
CTChart ctChart = chart.getCTChart();
CTPlotArea plotArea = ctChart.getPlotArea();
CTLineChart lineChart = plotArea.getLineChartArray(0);
List lineSerList = lineChart.getSerList(); // 获取折线图单位
//刷新内置excel数据
refreshExcel(chart, listItemsByType, fldNameArr, titleArr);
//刷新页面显示数据
refreshLineStrGraphContent(lineChart, lineSerList, listItemsByType, fldNameArr, 1);
}
/**
* 调用替换饼图数据
*/
public static void replacePieCharts(POIXMLDocumentPart poixmlDocumentPart,
List titleArr, List fldNameArr, List> listItemsByType) {
XWPFChart chart = (XWPFChart) poixmlDocumentPart;
chart.getCTChart();
//根据属性第一列名称切换数据类型
CTChart ctChart = chart.getCTChart();
CTPlotArea plotArea = ctChart.getPlotArea();
CTPieChart pieChart = plotArea.getPieChartArray(0);
List pieSerList = pieChart.getSerList(); // 获取饼图单位
//刷新内置excel数据
refreshExcel(chart, listItemsByType, fldNameArr, titleArr);
//刷新页面显示数据
refreshPieStrGraphContent(pieChart, pieSerList, listItemsByType, fldNameArr, 1);
}
/**
* 调用替换柱状图、折线图组合数据
*/
public static void replaceCombinationCharts(POIXMLDocumentPart poixmlDocumentPart,
List titleArr, List fldNameArr, List> listItemsByType) {
XWPFChart chart = (XWPFChart) poixmlDocumentPart;
chart.getCTChart();
//根据属性第一列名称切换数据类型
CTChart ctChart = chart.getCTChart();
CTPlotArea plotArea = ctChart.getPlotArea();
CTBarChart barChart = plotArea.getBarChartArray(0);
List barSerList = barChart.getSerList(); // 获取柱状图单位
//刷新内置excel数据
refreshExcel(chart, listItemsByType, fldNameArr, titleArr);
//刷新页面显示数据
refreshBarStrGraphContent(barChart, barSerList, listItemsByType, fldNameArr, 1);
CTBarChart barChart2 = plotArea.getBarChartArray(0);
List barSerList2 = barChart2.getSerList(); // 获取柱状图单位
//刷新内置excel数据
refreshExcel(chart, listItemsByType, fldNameArr, titleArr);
//刷新页面显示数据
refreshBarStrGraphContent(barChart2, barSerList2, listItemsByType, fldNameArr, 1);
CTLineChart lineChart = plotArea.getLineChartArray(0);
List lineSerList = lineChart.getSerList(); // 获取折线图单位
//刷新内置excel数据
refreshExcel(chart, listItemsByType, fldNameArr, titleArr);
//刷新页面显示数据
refreshLineStrGraphContent(lineChart, lineSerList, listItemsByType, fldNameArr, 1);
}
/**
* 刷新折线图数据方法
*
* @param typeChart
* @param serList
* @param dataList
* @param fldNameArr
* @param position
* @return
*/
public static boolean refreshLineStrGraphContent(Object typeChart,
List> serList, List> dataList, List 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", false);
cat.getStrRef().setF(axisDataRange);
//数据区域
String numDataRange = new CellRangeAddress(1, dataList.size(), i + position, i + position)
.formatAsString("Sheet1", false);
val.getNumRef().setF(numDataRange);
// 设置系列生成方向
}
return result;
}
/**
* 刷新柱状图数据方法
*
* @param typeChart
* @param serList
* @param dataList
* @param fldNameArr
* @param position
* @return
*/
public static boolean refreshBarStrGraphContent(Object typeChart,
List> serList, List> dataList, List 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 position
* @return
*/
public static boolean refreshPieStrGraphContent(Object typeChart,
List> serList, List> dataList, List 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
* @return
*/
public static boolean refreshExcel(XWPFChart chart,
List> dataList, List fldNameArr, List 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 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
List pxdList = chart.getRelations();
if(pxdList!=null&&pxdList.size()>0){
for(int i = 0;i
if(pxdList.get(i).toString().contains("sheet")){//判断为sheet再去进行更新表格数据
POIXMLDocumentPart xlsPart = pxdList.get(i);
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;
}
}
}
break;
}
}
}
return result;
}
/**
* 设置表格样式
*
* @param cell
* @param fontName
* @param fontSize
* @param fontBlod
* @param alignment
* @param vertical
* @param fontColor
* @param bgColor
* @param cellWidth
* @param content
*/
public static void setWordCellSelfStyle(XWPFTableCell cell, String fontName, String fontSize, int fontBlod,
String alignment, String vertical, String fontColor,
String bgColor, String 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());// 字体大小
}
// 设置单元格宽度
cell.setWidth(cellWidth);
//=====获取单元格
CTTc tc = cell.getCTTc();
//====tcPr开始====》》》》
CTTcPr tcPr = tc.getTcPr();//获取单元格里的
if (tcPr == null) {//没有,创建
tcPr = tc.addNewTcPr();
}
// --vjc开始-->>
CTVerticalJc vjc = tcPr.getVAlign();//获取 的
if (vjc == null) {//没有,创建
vjc = tcPr.addNewVAlign();
}
//设置单元格对齐方式
vjc.setVal(vertical.equals("top") ? STVerticalJc.TOP : vertical.equals("bottom") ? STVerticalJc.BOTTOM : STVerticalJc.CENTER); //垂直对齐
CTShd shd = tcPr.getShd();//获取里的
if (shd == null) {//没有,创建
shd = tcPr.addNewShd();
}
// 设置背景颜色
shd.setFill(bgColor.substring(1));
//《《《《====tcPr结束====
//====p开始====》》》》
CTP p = tc.getPList().get(0);//获取单元格里的
//---ppr开始--->>>
CTPPr ppr = p.getPPr();//获取
里的
if (ppr == null) {//没有,创建
ppr = p.addNewPPr();
}
// --jc开始-->>
CTJc jc = ppr.getJc();//获取里的
if (jc == null) {//没有,创建
jc = ppr.addNewJc();
}
//设置单元格对齐方式
jc.setVal(alignment.equals("left") ? STJc.LEFT : alignment.equals("right") ? STJc.RIGHT : STJc.CENTER); //水平对齐
// <
// --pRpr开始-->>
CTParaRPr pRpr = ppr.getRPr(); //获取里的
if (pRpr == null) {//没有,创建
pRpr = ppr.addNewRPr();
}
CTFonts pfont = pRpr.getRFonts();//获取里的
if (pfont == null) {//没有,创建
pfont = pRpr.addNewRFonts();
}
//设置字体
pfont.setAscii(fontName);
pfont.setEastAsia(fontName);
pfont.setHAnsi(fontName);
CTOnOff pb = pRpr.getB();//获取里的
if (pb == null) {//没有,创建
pb = pRpr.addNewB();
}
//设置字体是否加粗
pb.setVal(fontBlod == 1 ? STOnOff.ON : STOnOff.OFF);
CTHpsMeasure psz = pRpr.getSz();//获取里的
if (psz == null) {//没有,创建
psz = pRpr.addNewSz();
}
// 设置单元格字体大小
psz.setVal(bFontSize);
CTHpsMeasure pszCs = pRpr.getSzCs();//获取里的
if (pszCs == null) {//没有,创建
pszCs = pRpr.addNewSzCs();
}
// 设置单元格字体大小
pszCs.setVal(bFontSize);
// <
//<<
//---r开始--->>>
List rlist = p.getRList(); //获取
里的
CTR r = null;
if (rlist != null && rlist.size() > 0) {//获取第一个
r = rlist.get(0);
} else {//没有,创建
r = p.addNewR();
}
//--rpr开始-->>
CTRPr rpr = r.getRPr();//获取里的
if (rpr == null) {//没有,创建
rpr = r.addNewRPr();
}
//->-
CTFonts font = rpr.getRFonts();//获取里的
if (font == null) {//没有,创建
font = rpr.addNewRFonts();
}
//设置字体
font.setAscii(fontName);
font.setEastAsia(fontName);
font.setHAnsi(fontName);
CTOnOff b = rpr.getB();//获取里的
if (b == null) {//没有,创建
b = rpr.addNewB();
}
//设置字体是否加粗
b.setVal(fontBlod == 1 ? STOnOff.ON : STOnOff.OFF);
CTColor color = rpr.getColor();//获取里的
if (color == null) {//没有,创建
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);
//-
//<
List tlist = r.getTList();
CTText t = null;
if (tlist != null && tlist.size() > 0) {//获取第一个
t = tlist.get(0);
} else {//没有,创建
t = r.addNewT();
}
t.setStringValue(content);
//<<
}
}