感谢以下博客
1.java使用poi操作world生成饼图,柱状图,折线图,组合图:二_不知所终的博客-CSDN博客2.java使用poi在word中生成柱状图、折线图、饼图、柱状图+折线图组合图、动态表格、文本替换、图片替换、更新内置Excel数据、更新插入的文本框内容、合并表格单元格;_u014427811的博客-CSDN博客
本文参考以上两个博客,并做了部分修改做了记录
解决的问题
1.填充数据后,图例却没动态改变,还是模板里的图例。
数据分析时,需要往图形缓存里赋值图例标题
2.动态删除图表,如有要求,图表没有数据时动态删除图表。
通过图形所在段落位置删除的,没找到其他方法。
图形的位置是通过一段文字位置的找到,比如我的图形在“1)到访游客规模”下面,我先找到这个文字的位置,文字的位置+1就是我图形的位置。哈哈,有点牵强,但是没找到其他办法。
获取图片的位置
private Integer getParagraphIndex(List<XWPFParagraph> xwpfParagraphList,String mark) {
for (int i=0;i<xwpfParagraphList.size();i++){
XWPFParagraph paragraph=xwpfParagraphList.get(i);
List<XWPFRun> xwpfRuns= paragraph.getRuns();
String runStr="";
for (int z=0; z<xwpfRuns.size(); z++) {
runStr+=xwpfRuns.get(z).toString();
}
if(mark.equals(runStr)){
return i+1;
}
}
return null;
}
3.假如我们模板某个折线图有四条数据,但实际我们填充的数据只填充了两条,最后生成的图表里会有四条数据,前两条就是我们实际的数据,后两条我们填充数据,模板数据却保留了。
新增图标数据前,先删除调模板里边的数据,不知道为啥滴倒着删,正着顺序会乱。。。
1.准备一个简单的word模板,后缀名为.docx
2.上代码
测试类
说明:dataSource是数据源,可通过调接口获取json格式数据
wordTemplete可配置系统参数里,定义图标位置及类型等,可动态改变word模板里的图形,不用改动代码。
package com.asiainfo.srd.bd.report.controller;
import com.alibaba.fastjson.JSONObject;
import com.asiainfo.srd.bd.common.utils.StringUtils;
import com.asiainfo.srd.bd.report.domain.ChartModel;
import com.asiainfo.srd.bd.report.domain.ChartsEnum;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.xwpf.usermodel.XWPFChart;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Test {
public static void main(String[] args) throws IOException, InvalidFormatException {
//获取word模板
InputStream docis = new FileInputStream("E:\\报告新.docx");
//转成word
XWPFDocument doc = new XWPFDocument(docis);
List<XWPFChart> charts = doc.getCharts();
Map<String, XWPFChart> chartsMap = new HashMap<String, XWPFChart>();
for (XWPFChart chart : charts) {
String s = chart.toString();
String key = s.replaceAll("Name: ", "")
.replaceAll(" - Content Type: application/vnd\\.openxmlformats-officedocument\\.drawingml\\.chart\\+xml", "").trim();
System.out.println("key:" + key);
chartsMap.put(key, chart);
}
String dataSorce = "{\n" +
"\t\"model\": {\n" +
"\t\t\"textParams\": {\n" +
"\t\t\t\"p1\": \"2020\",\n" +
"\t\t\t\"p2\": \"2021\"\n" +
"\t\t},\n" +
"\t\t\"chartsModel\": [\n" +
"\t\t\t[\n" +
"\t\t\t\t{\n" +
"\t\t\t\t\t\"xAxis\": {\n" +
"\t\t\t\t\t\t\"月份\": \"2021年10月1日\"\n" +
"\t\t\t\t\t},\n" +
"\t\t\t\t\t\"data\": {\n" +
"\t\t\t\t\t\t\"到访游客规模\": \"100.0\"\n" +
"\t\t\t\t\t}\n" +
"\t\t\t\t},\n" +
"\t\t\t\t{\n" +
"\t\t\t\t\t\"xAxis\": {\n" +
"\t\t\t\t\t\t\"月份\": \"2021年10月2日\"\n" +
"\t\t\t\t\t},\n" +
"\t\t\t\t\t\"data\": {\n" +
"\t\t\t\t\t\t\"到访游客规模\": \"200\"\n" +
"\t\t\t\t\t}\n" +
"\t\t\t\t}\n" +
"\t\t\t\t{\n" +
"\t\t\t\t\t\"xAxis\": {\n" +
"\t\t\t\t\t\t\"月份\": \"2021年10月3日\"\n" +
"\t\t\t\t\t},\n" +
"\t\t\t\t\t\"data\": {\n" +
"\t\t\t\t\t\t\"到访游客规模\": \"300\"\n" +
"\t\t\t\t\t}\n" +
"\t\t\t\t},\n" +
"\t\t\t\t{\n" +
"\t\t\t\t\t\"xAxis\": {\n" +
"\t\t\t\t\t\t\"月份\": \"2021年10月4日\"\n" +
"\t\t\t\t\t},\n" +
"\t\t\t\t\t\"data\": {\n" +
"\t\t\t\t\t\t\"到访游客规模\": \"400\"\n" +
"\t\t\t\t\t}\n" +
"\t\t\t\t}\n" +
"\t\t\t]\n" +
"\t\t]\n" +
"\t}\n" +
"}";
//格式化系统参数
String wordTemplete = "{\n" +
"\t\"textMap\": {\n" +
"\t\t\"param1\": \"p1\"\n" +
"\t},\n" +
"\t\"chartsMap\": [\n" +
"\t\t{\n" +
"\t\t\t\"dataSourceIndex\": 0,\n" +
"\t\t\t\"chartIndex\": 1,\n " +
"\t\t\t\"chartType\": 3\n" +
"\t\t}" +
"\t]\n" +
"}";
System.out.println(wordTemplete);
Map mapObj = JSONObject.parseObject(wordTemplete, Map.class);
Map<String, Object> textMap = (Map<String, Object>) mapObj.get("textMap");
List<Map<String, Object>> chartsList = (List<Map<String, Object>>) mapObj.get("chartsMap");
//格式数据源
Map dataSorceMap = JSONObject.parseObject(dataSorce, Map.class);
Map model = (Map) dataSorceMap.get("model");
Map<String, Object> textParams = (Map<String, Object>) model.get("textParams");
List<List<Map<String, Map<String, String>>>> chartsModelSorce = (List<List<Map<String, Map<String, String>>>>) model.get("chartsModel");
for (String key : textMap.keySet()) {
//key为文档上变量
//变量对应的值
Object o = textParams.get(textMap.get(key));
}
for (Map<String, Object> map : chartsList) {
if (StringUtils.isNotEmpty(map.get("chartIndex").toString())
&& StringUtils.isNotEmpty(map.get("chartType").toString())
&& StringUtils.isNotEmpty(map.get("dataSourceIndex").toString())) {
//图形在word模板中的位置
String chartIndex = map.get("chartIndex").toString();
//图形的类型,如折线图,饼形图等
String chartType = map.get("chartType").toString();
//取数据源的位置
int dataSourceIndex = Integer.valueOf(map.get("dataSourceIndex").toString());
//组织数据
List<Map<String, Map<String, String>>> list = chartsModelSorce.get(dataSourceIndex);
List<String> titleList = new ArrayList<String>();
List<String> numberList = new ArrayList();
List<Map<String, String>> sourceModelList = new ArrayList<>();
if (list.size() > 0) {
for (int i = 0; i < list.size(); i++) {
Map<String, Map<String, String>> m = list.get(i);
Map<String, String> xAxis = m.get("xAxis");
Map<String, String> data = m.get("data");
if (i == 0) {
titleList.addAll(new ArrayList(xAxis.keySet()));
numberList.addAll(new ArrayList(xAxis.keySet()));
titleList.addAll(new ArrayList(data.keySet()));
numberList.addAll(new ArrayList(data.keySet()));
}
Map<String, String> sourceModeMap = new HashMap<>();
sourceModeMap.putAll(xAxis);
sourceModeMap.putAll(data);
sourceModelList.add(sourceModeMap);
}
//数据源
ChartModel chartModel = new ChartModel();
chartModel.setNumberList(numberList);
chartModel.setTitleList(titleList);
chartModel.setSourceModelList(sourceModelList);
//
chartModel.setSingleChart(chartsMap, chartIndex, 0, ChartsEnum.getInstance(chartType));
chartModel.executeFillModel("sheet1");
}
}
}
try (FileOutputStream fos = new FileOutputStream("E://test.docx")) {
doc.write(fos);
doc.write(fos);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// System.out.println(textMap.toString());
}
}
工具类
1.chartModel.class
package com.asiainfo.srd.bd.report.domain;
import lombok.Getter;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.xwpf.usermodel.XWPFChart;
import org.apache.xmlbeans.XmlObject;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTChart;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author BM_hyjw
* 图表要填充的数据格式
*/
@Slf4j
@Getter
@ToString
public class ChartModel {
/**
* 标记 用来记录当前是否是单元素的图表
*/
private Boolean isSingle = true;
/**
* 内置表格页名
*/
private String sheetName;
/**
* 图表
*/
private XWPFChart xwpfChart;
/**
* 具体图
*/
private List<XmlObject> xmlObjectList = new ArrayList<>();
/**
* 绘制区域图
*/
private CTChart ctChart;
/**
* 标题
*/
private List<String> titleList;
/**
* 数据源对应的key
*/
private List<String> numberList;
/**
* 填充的数据源
*/
private List<Map<String, String>> sourceModelList;
/**
* 目标数据
*/
private List<ChartsEnum> chartsEnumList;
/**
* 赋值 替换目标
* @param numberList
*/
public void setNumberList(List<String> numberList){
this.numberList = numberList;
}
/**
* 赋值 数据源
* @param sourceModelList
*/
public void setSourceModelList(List<Map<String, String>> sourceModelList){
this.sourceModelList = sourceModelList;
}
/**
* 赋值 标题
* @param titleList
*/
public void setTitleList(List<String> titleList){
this.titleList = titleList;
}
/**
* 单个赋值 图表
* @param charts 所有可绘制区域
* @param chartSeat 要操作的图表中可绘制区域位置
* @param xmlObjSeat 图表在可绘制区域中的位置
* @param chartsEnum 目标的表格类型
*/
public void setSingleChart(Map<String,XWPFChart> charts,String chartSeat,int xmlObjSeat,ChartsEnum chartsEnum){
List<ChartsEnum> chartsEnumList = Arrays.asList(chartsEnum);
/**
* 封装基础数据
*/
this.packageBasic(charts, chartSeat,chartsEnumList);
/**
* 获得目标图表
*/
XmlObject targetChart = chartsEnum.getTargetChart(chartSeat, this.ctChart, xmlObjSeat);
this.xmlObjectList = Arrays.asList(targetChart);
//当前是单元素
this.isSingle = true;
}
/**
* 组合赋值 图表
* @param charts 所有可绘制区域
* @param chartSeat 要操作的图表中可绘制区域位置
* @param xmlObjSeat 图表在可绘制区域中的位置
* @param chartsEnumList 目标的表格类型
*/
public void setComBiChart(Map<String,XWPFChart> charts,String chartSeat,int xmlObjSeat,List<ChartsEnum> chartsEnumList){
/**
* 封装基础数据
*/
this.packageBasic(charts, chartSeat,chartsEnumList);
/**
* 获得目标图表
*/
this.xmlObjectList.clear();
chartsEnumList.stream().forEach(x->{
XmlObject targetChart = x.getTargetChart(chartSeat,this.ctChart, xmlObjSeat);
this.xmlObjectList.add(targetChart);
});
//当前不是单元素
this.isSingle = false;
}
/**
* 封装部分基础数据
* @param charts
* @param chartSeat
* @param chartsEnumList
*/
private void packageBasic(Map<String,XWPFChart> charts, String chartSeat,List<ChartsEnum> chartsEnumList) {
if(CollectionUtils.isEmpty(charts)){
throw new RuntimeException("模板中图表元素为null; !!!ctChart:null");
}
if(CollectionUtils.isEmpty(chartsEnumList)){
throw new RuntimeException("图表目标为null;!!!chartsEnum:null");
}
/**
* 目标
*/
this.chartsEnumList = chartsEnumList;
/**
* 第N个位置图表
*/
this.xwpfChart = charts.get("/word/charts/chart"+chartSeat+".xml");
/**
* 第N个位置可绘制区域的图表
*/
this.ctChart = this.xwpfChart.getCTChart();
}
/**
* 执行模板数据源填充
* @param sheetName 展示数据excel页名字
*/
public void executeFillModel(String sheetName) throws IOException, InvalidFormatException {
this.sheetName = sheetName;
//异常校验
String s = this.isSingle ? this.abnormalCheckSingle() : this.abnormalCheckComBi();
//执行填充数据
ChartsEnum.refreshExcel(this);
for (int i = 0; i < chartsEnumList.size(); i++) {
ChartsEnum chartsEnum = chartsEnumList.get(i);
chartsEnum.fillModel(this,this.getXmlObjectList().get(i),i);
}
// //标题
// List<String> titleList = getTitleList();
}
/**
* 异常校验
*/
private String abnormalCheckSingle() {
// if(CollectionUtils.isEmpty(this.numberList)){
// throw new RuntimeException("数据源比对为null; !!!numberList:null");
// }
// if(CollectionUtils.isEmpty(this.titleList)){
// throw new RuntimeException("标题为null; !!!titleList:null");
// }
// if(CollectionUtils.isEmpty(this.sourceModelList)){
// throw new RuntimeException("数据源为null; !!!sourceModelList:null");
// }
if(Objects.isNull(this.xwpfChart)){
throw new RuntimeException("模板中图表元素为null; !!!xwpfChart:null");
}
if(CollectionUtils.isEmpty(this.xmlObjectList)){
throw new RuntimeException("模板中具体图表为null;!!!xmlObjectList:null");
}
if(CollectionUtils.isEmpty(this.chartsEnumList)){
throw new RuntimeException("图表目标为null;!!!chartsEnum:null");
}
if(Objects.isNull(this.ctChart)){
throw new RuntimeException("图表绘制区域为null;!!!chartsEnum:null");
}
if(StringUtils.isEmpty(this.sheetName)){
throw new RuntimeException("内置excel页名为null;!!!sheetName:null");
}
return null;
}
/**
* 异常校验
*/
private String abnormalCheckComBi() {
this.abnormalCheckSingle();
if (this.xmlObjectList.size() < 2) {
throw new RuntimeException("组合图中【图表】元素不足两个; !!!xmlObjectList.size !> 2");
}
if (this.sourceModelList.stream().filter(x->{return x.keySet().size() >= 3;}).collect(Collectors.toList()).size() < 0) {
throw new RuntimeException("组合图中【数据源】元素不足两个; !!!sourceModelList.map.keySet.size !>= 3");
}
if (this.numberList.size() < 3) {
throw new RuntimeException("组合图中【数据源对应的key】元素不足两个; !!!numberList.size !>= 3");
}
return null;
}
}
2.ChartsEnums.java
package com.asiainfo.srd.bd.report.domain;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
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.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlString;
import org.apache.xmlbeans.impl.values.XmlComplexContentImpl;
import org.openxmlformats.schemas.drawingml.x2006.chart.*;
import org.openxmlformats.schemas.drawingml.x2006.chart.impl.CTBarChartImpl;
import org.openxmlformats.schemas.drawingml.x2006.chart.impl.CTLineChartImpl;
import org.openxmlformats.schemas.drawingml.x2006.chart.impl.CTPieChartImpl;
import org.openxmlformats.schemas.drawingml.x2006.chart.impl.CTScatterChartImpl;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
/**
* @author BM_hyjw
* 解析world 中图表
*/
@Slf4j
@Getter
public enum ChartsEnum {
/**
* 饼图
*/
PIE(CTPieChart.class, CTPieChartImpl.class,"1","饼图"){
/**
* 填充模板数据
* @param chartModel 图表和数据源
* @param xmlObject 当前元素
* @param bias 偏向值
*/
@Override
public void fillModel(ChartModel chartModel, XmlObject xmlObject, int bias) {
if (!this.chartImplClazz.getName().equals(xmlObject.getClass().getName())) {
//当前循环中图表操作不属于当前枚举
ChartsEnum.getEnumByChartImplClazz(((XmlComplexContentImpl)xmlObject).getClass())
.fillModel(chartModel, xmlObject, bias);
return;
}
CTPieChart pieChart = (CTPieChart)xmlObject;
List<CTPieSer> serList = pieChart.getSerList();
//更新数据区域
for (int i = 0; i < serList.size(); i++) {
//数据填充
//
CTPieSer ser = pieChart.getSerArray(i);
CTAxDataSource cat = ser.getCat();
CTNumDataSource val = ser.getVal();
// this.dataAnalysisFill(chartModel,i,bias,cat,val);
CTSerTx tx = ser.getTx();
this.dataAnalysisFill(chartModel,i,bias,cat,val,tx);
}
}
/**
* 得到目标位置的图表
* @param ctChart 可绘制区域图表
* @param xmlObjSeat 目标图标位置位置
* @return
*/
@Override
public XmlObject getTargetChart(String chartSeat, CTChart ctChart, int xmlObjSeat) {
try {
CTPieChart pieChart = ctChart.getPlotArea().getPieChartArray(xmlObjSeat);
return pieChart;
}catch (Exception e){
throw new RuntimeException("当前位置【" + chartSeat + "】不存在【饼图】!!!");
}
}
},
/**
* 柱图
*/
COLUMN(CTBarChart.class, CTBarChartImpl.class,"2","柱形图") {
/**
* 填充模板数据
* @param chartModel 图表和数据源
* @param bias 偏向值
*/
@Override
public void fillModel(ChartModel chartModel,XmlObject xmlObject,int bias) {
if (!this.chartImplClazz.getName().equals(xmlObject.getClass().getName())) {
//当前循环中图表操作不属于当前枚举
ChartsEnum.getEnumByChartImplClazz(((XmlComplexContentImpl)xmlObject).getClass())
.fillModel(chartModel, xmlObject, bias);
return;
}
CTBarChart chart = (CTBarChart)xmlObject;
List<CTBarSer> serList = chart.getSerList();
//更新数据区域
for (int i = 0; i < serList.size(); i++) {
//数据填充
//
CTBarSer ser = chart.getSerArray(i);
CTAxDataSource cat = ser.getCat();
CTNumDataSource val = ser.getVal();
// this.dataAnalysisFill(chartModel,i,bias,cat,val);
CTSerTx tx = ser.getTx();
this.dataAnalysisFill(chartModel,i,bias,cat,val,tx);
}
}
/**
* 得到目标位置的图表
* @param ctChart 可绘制区域图表
* @param xmlObjSeat 目标图标位置位置
* @return
*/
@Override
public XmlObject getTargetChart(String chartSeat, CTChart ctChart, int xmlObjSeat) {
try {
CTBarChart barChart = ctChart.getPlotArea().getBarChartArray(xmlObjSeat);
return barChart;
}catch (Exception e){
throw new RuntimeException("当前位置【" + chartSeat + "】不存在【柱状图】!!!");
}
}
},
/**
* 折线图
*/
LINE_CHART(CTLineChart.class, CTLineChartImpl.class,"3","折线图"){
/**
* 填充模板数据
* @param chartModel 图表和数据源
* @param xmlObject 当前元素
* @param bias 偏向值
*/
@Override
public void fillModel(ChartModel chartModel,XmlObject xmlObject,int bias) {
if (!this.chartImplClazz.getName().equals(xmlObject.getClass().getName())) {
//当前循环中图表操作不属于当前枚举
ChartsEnum.getEnumByChartImplClazz(((XmlComplexContentImpl)xmlObject).getClass())
.fillModel(chartModel, xmlObject, bias);
return;
}
CTLineChart chart = (CTLineChart)xmlObject;
List<CTLineSer> serList = chart.getSerList();
//更新数据区域
for (int i = 0; i < serList.size(); i++) {
//数据填充
//
CTLineSer ser = chart.getSerArray(i);
CTAxDataSource cat = ser.getCat();
CTNumDataSource val = ser.getVal();
CTSerTx tx = ser.getTx();
this.dataAnalysisFill(chartModel,i,bias,cat,val,tx);
}
}
/**
* 得到目标位置的图表
* @param ctChart 可绘制区域图表
* @param xmlObjSeat 目标图标位置位置
* @return
*/
@Override
public XmlObject getTargetChart(String chartSeat, CTChart ctChart, int xmlObjSeat) {
try {
CTLineChart lineChart = ctChart.getPlotArea().getLineChartArray(xmlObjSeat);
return lineChart;
}catch (Exception e){
throw new RuntimeException("当前位置【" + chartSeat + "】不存在【折线图】!!!");
}
}
},
/**
* 散点图
*/
SCATTER(CTScatterChart.class, CTScatterChartImpl.class,"4","散点图"){
/**
* 填充模板数据
* @param chartModel 图表和数据源
* @param xmlObject 当前元素
* @param bias 偏向值
*/
@Override
public void fillModel(ChartModel chartModel,XmlObject xmlObject,int bias) {
if (!this.chartImplClazz.getName().equals(xmlObject.getClass().getName())) {
//当前循环中图表操作不属于当前枚举
ChartsEnum.getEnumByChartImplClazz(((XmlComplexContentImpl)xmlObject).getClass())
.fillModel(chartModel, xmlObject, bias);
return;
}
CTScatterChart chart = (CTScatterChart)xmlObject;
List<CTScatterSer> serList = chart.getSerList();
//更新数据区域
for (int i = 0; i < serList.size(); i++) {
//数据填充
//
CTScatterSer ser = chart.getSerArray(i);
CTAxDataSource cat = ser.getXVal();
CTNumDataSource val = ser.getYVal();
CTSerTx tx = ser.getTx();
this.dataAnalysisFill(chartModel,i,bias,cat,val,tx);
}
}
/**
* 得到目标位置的图表
* @param ctChart 可绘制区域图表
* @param xmlObjSeat 目标图标位置位置
* @return
*/
@Override
public XmlObject getTargetChart(String chartSeat, CTChart ctChart, int xmlObjSeat) {
try {
CTScatterChart scatterChart = ctChart.getPlotArea().getScatterChartArray(xmlObjSeat);
return scatterChart;
}catch (Exception e){
throw new RuntimeException("当前位置【" + chartSeat + "】不存在【散点图】!!!");
}
}
},
;
/**
* 图表对象
*/
public Class<? extends XmlObject> chartClazz;
private String code;
private String msg;
/**
* 图表实现对象
*/
public Class<? extends XmlComplexContentImpl> chartImplClazz;
ChartsEnum(Class<? extends XmlObject> chartClazz,
Class<? extends XmlComplexContentImpl> chartImplClazz,String code, String msg){
this.chartClazz = chartClazz;
this.chartImplClazz = chartImplClazz;
this.code = code;
this.msg = msg;
}
/**
* 根据code获取枚举实例
* @param code
* @return
*/
public static ChartsEnum getInstance(String code){
for (ChartsEnum each : ChartsEnum.values()){
if (each.getCode().equals(code)){
return each;
}
}
return null;
}
/**
* 填充模板数据
* @param chartModel 图表和数据源
* @param xmlObject 当前元素
* @param bias 偏向值
*/
public abstract void fillModel(ChartModel chartModel,XmlObject xmlObject,int bias);
/**
* 得到目标位置的图表
* @param chartSeat 位置
* @param ctChart 可绘制区域图表
* @param xmlObjSeat 目标图标位置位置
*/
public abstract XmlObject getTargetChart(String chartSeat,CTChart ctChart,int xmlObjSeat);
/**
* 根据值来源得到对应的 图表实现对象
* @param chartImplClazz 图表实现对象
* @return
*/
public static ChartsEnum getEnumByChartImplClazz(Class<? extends XmlComplexContentImpl> chartImplClazz){
for (ChartsEnum value : ChartsEnum.values()) {
if (value.getChartImplClazz().equals(chartImplClazz)){
return value;
}
}
return null;
}
/**
* 根据值来源得到对应的 图表对象
* @param chartClazz 图表对象
* @return
*/
public static ChartsEnum getEnumByChartClazz(Class<? extends XmlObject> chartClazz){
for (ChartsEnum value : ChartsEnum.values()) {
if (value.getChartClazz().equals(chartClazz)){
return value;
}
}
return null;
}
/**
* 刷新内置excel数据
* @return
*/
public static boolean refreshExcel(ChartModel chartModel) throws IOException, InvalidFormatException {
List<String> titleList = chartModel.getTitleList();
List<String> numberList = chartModel.getNumberList();
List<Map<String, String>> sourceModelList = chartModel.getSourceModelList();
XWPFChart xwpfChart = chartModel.getXwpfChart();
boolean result = true;
Workbook wb = new XSSFWorkbook();
Sheet sheet = wb.createSheet(chartModel.getSheetName());
//根据数据创建excel第一行标题行
if(titleList.size()>0){
//没有数据的建立空表
sheet.createRow(0).createCell(0).setCellValue("");
sheet.getRow(0).createCell(1).setCellValue("");
}
for (int i = 0; i < titleList.size(); i++) {
if (sheet.getRow(0) == null) {
sheet.createRow(0).createCell(i).setCellValue(titleList.get(i) == null ? "" : "");
} else {
sheet.getRow(0).createCell(i).setCellValue(titleList.get(i) == null ? "" : titleList.get(i));
}
}
//遍历数据行
if(titleList.size()<0){
sheet.createRow(1).createCell(0).setCellValue("");
sheet.getRow(1).createCell(1).setCellValue("");
}
for (int i = 0; i < sourceModelList.size(); i++) {
Map<String, String> baseFormMap = sourceModelList.get(i);//数据行
//fldNameArr字段属性
for (int j = 0; j < numberList.size(); j++) {
if (sheet.getRow(i + 1) == null) {
if (j == 0) {
try {
sheet.createRow(i + 1)
.createCell(j)
.setCellValue(baseFormMap.get(numberList.get(j)) == null ?
"" : baseFormMap.get(numberList.get(j)));
} catch (Exception e) {
if (baseFormMap.get(numberList.get(j)) == null) {
sheet.createRow(i + 1).createCell(j).setCellValue("");
} else {
sheet.createRow(i + 1)
.createCell(j)
.setCellValue(baseFormMap.get(numberList.get(j))+"");
}
}
}
} else {
// String s = baseFormMap.get(numberList.get(j))+"";
// Double aDouble = Double.valueOf(baseFormMap.get(numberList.get(j)));
BigDecimal b = new BigDecimal(Double.valueOf(baseFormMap.get(numberList.get(j))));
double value = 0D;
if (b != null) {
value = b.doubleValue();
}
sheet.getRow(i + 1).createCell(j).setCellValue(b.doubleValue());
// if (value == 0D) {
// sheet.getRow(i + 1).createCell(j);
// } else {
// sheet.getRow(i + 1).createCell(j).setCellValue(b.doubleValue());
// }
}
}
}
// 更新嵌入的workbook
List<POIXMLDocumentPart> pxdList = xwpfChart.getRelations();
if(pxdList!=null&&pxdList.size()>0) {
for (int i = 0; i < pxdList.size(); i++) {
if (pxdList.get(i).toString().contains("sheet")) {
POIXMLDocumentPart xlsPart = xwpfChart.getRelations().get(0);
OutputStream xlsOut = xlsPart.getPackagePart().getOutputStream();
try {
xlsOut.flush();
wb.write(xlsOut);
xlsPart.setCommitted(true);
// ((XSSFWorkbook) wb).setCommitted(true);
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 chartModel
* @param i
* @param bias
* @param cat
* @param val
*/
public void dataAnalysisFill (ChartModel chartModel,
int i,
int bias,
CTAxDataSource cat,
CTNumDataSource val,
CTSerTx tx) {
//数据源
List<Map<String, String>> sourceModelList = chartModel.getSourceModelList();
//数据源key
List<String> numberList = chartModel.getNumberList();
List<String> titleList = chartModel.getTitleList();
//
CTStrData strData = cat.getStrRef().getStrCache();
CTNumData numData = val.getNumRef().getNumCache();
long idx = 0;
//1、删掉模板里图表缓存数据
long l=strData.getPtCount().getVal();
long z=0;
long num=l;
while (z!=num){
numData.removePt((int)l-1);
strData.removePt((int)l-1);
l--;
z++;
}
//2.新增图表数据
for (int j = 0; j < sourceModelList.size(); j++) {
//判断获取的值是否为空
String value = "0";
if (new BigDecimal(sourceModelList.get(j).get(numberList.get(i+1))) != null) {
value = new BigDecimal(sourceModelList.get(j).get(numberList.get(i + 1))).toString();
}
CTNumVal numVal = numData.addNewPt();//序列值
numVal.setIdx(idx);
numVal.setV(value);
// if (!"0".equals(value)) {
// CTNumVal numVal = numData.addNewPt();//序列值
// numVal.setIdx(idx);
// numVal.setV(value);
// }
CTStrVal sVal = strData.addNewPt();//序列名称
sVal.setIdx(idx);
sVal.setV(sourceModelList.get(j).get(numberList.get(0)));
idx++;
}
//3.图表没有数据,默认值,以便能显示出图表
int m=sourceModelList.size();
if(titleList.size()==0){
idx=1;
m=1;
}
numData.getPtCount().setVal(idx);
strData.getPtCount().setVal(idx);
//赋值横坐标数据区域
String axisDataRange = new
CellRangeAddress(1, m, 0, 0)
.formatAsString(chartModel.getSheetName(), false);
cat.getStrRef().setF(axisDataRange);
//赋值纵坐标数据区域
String numDataRange = new
CellRangeAddress(1, m, i + 1 + bias, i + 1 + bias)
.formatAsString(chartModel.getSheetName(), false);
val.getNumRef().setF(numDataRange);
//更新图例
if(sourceModelList.size()>0){
tx.getStrRef().getStrCache().getPtList().get(0).setV(titleList.get(i+1));
}
}
}