写点什么

java 使用 poi 操作 world 生成饼图,柱状图,折线图,java 微服务架构训练营

用户头像
极客good
关注
发布于: 刚刚

List<XWPFChart> charts = doc.getCharts();


//数据源


ChartModel chartModel = new ChartModel();


//标题


List<String> titleList = new ArrayList<String>();


titleList.add("type");


titleList.add("number");


chartModel.setTitleList(titleList);


//字段名


List<String> numberList = new ArrayList<String>();


numberList.add("value1");


numberList.add("value2");


chartModel.setNumberList(numberList);


//记录某本书销售多少册


List<Map<String, String>> sourceModelList = new ArrayList<>();


Map<String, String> publicEm = new HashMap<>();


publicEm.put("value1", "设计模式之禅");


publicEm.put("value2", "555");


Map<String, String> publicEm1 = new HashMap<>();


publicEm1.put("value1", "effective java");


publicEm1.put("value2", "453");


Map<String, String> publicEm2 = new HashMap<>();


publicEm2.put("value1", "红楼梦");


publicEm2.put("value2", "982");


Map<String, String> publicEm3 = new HashMap<>();


publicEm3.put("value1", "水浒传");


publicEm3.put("value2", "759");


sourceModelList.add(publicEm);


sourceModelList.add(publicEm1);


sourceModelList.add(publicEm2);


sourceModelList.add(publicEm3);


chartModel.setSourceModelList(sourceModelList);


//得到模板中第 N 个位置的图表可绘制区域中 条形图


chartModel.setSingleChart(charts,2,0,ChartsEnum.COLUMN);


chartModel.executeFillModel("sheet1");


//得到模板中第 N 个位置的图表可绘制区域中 饼状图


chartModel.setSingleChart(charts,3,0,ChartsEnum.PIE);


chartModel.executeFillModel("sheet1");


//得到模板中第 N 个位置的图表可绘制区域中 折线图


chartModel.setSingleChart(charts,4,0,ChartsEnum.LINE_CHART);


chartModel.executeFillModel("sheet1");


try (FileOutputStream fos = new FileOutputStream("test.docx")) {


doc.write(fos);


} catch (FileNotFoundException e) {


e.printStackTrace();


} catch (IOException e) {


e.printStackTrace();


}


}


}


[](


)测试类:组合图表(入口)




第一个图表:


对应 Map 数据源中第一个 key 做 X 轴 第二个 key 做 Y 轴


第二个图表:


对应 Map 数据源中第一个 key 做 X 轴 第三个 key 做 Y 轴


import lombok.SneakyThrows;


import org.apache.poi.openxml4j.exceptions.InvalidFormatException;


import org.apache.poi.xwpf.usermodel.XWPFChart;


import java.io.*;


import java.util.*;


/**


  • @author BM_hyjw

  • word 图表写入数据实现测试


*/


public class Combination{


@SneakyThrows


public static void main(String[] args) {


//获取 word 模板


InputStream docis = new FileInputStream("C:\Users\16630\Desktop\htmlToLongImage\haha.docx");


//转成 word


CustomXWPFDocument doc = new CustomXWPFDocument(docis);


//获取 word 中所有图表对象


List<XWPFChart> charts = doc.getCharts();


//数据源


ChartModel chartModel = new ChartModel();


//标题


List<String> titleList = new ArrayList<String>();


titleList.add("type");


titleList.add("number");


titleList.add("max");


chartModel.setTitleList(titleList);


//字段名


List<String> numberList = new ArrayList<String>();


numberList.add("value1");


numberList.add("value2");


numberList.add("value3");


chartModel.setNumberList(numberList);


//记录某本书销售多少册


List<Map<String, String>> sourceModelList = new ArrayList<>();


Map<String, String> publicEm = new HashMap<>();


publicEm.put("value1", "设计模式之禅");


publicEm.put("value2", "555");


publicEm.put("value3", "0");


Map<String, String> publicEm1 = new HashMap<>();


publicEm1.put("value1", "effective java");


publicEm1.put("value2", "453");


publicEm1.put("value3", "0");


Map<String, String> publicEm2 = new HashMap<>();


publicEm2.put("value1", "红楼梦");


publicEm2.put("value2", "982");


publicEm2.put("value3", "982");


Map<String, String> publicEm3 = new HashMap<>();


publicEm3.put("value1", "水浒传");


publicEm3.put("value2", "759");


publicEm3.put("value3", "759");


sourceModelList.add(publicEm);


sourceModelList.add(publicEm1);


sourceModelList.add(publicEm2);


sourceModelList.add(publicEm3);


chartModel.setSourceModelList(sourceModelList);


//得到模板中第 N 个位置的图表可绘制区域中 折线图 和 柱状图 的 组合图


chartModel.setComBiChart(charts,0,0,


Arrays.asList(ChartsEnum.LINE_CHART,ChartsEnum.COLUMN));


chartModel.executeFillModel("sheet1");


//得到模板中第 N 个位置的图表可绘制区域中 折线图 和 散点 的 组合图


chartModel.setComBiChart(charts,1,0,


Arrays.asList(ChartsEnum.LINE_CHART,ChartsEnum.SCATTER));


chartModel.executeFillModel("sheet1");


try (FileOutputStream fos = new FileOutputStream("test.docx")) {


doc.write(fos);


} catch (FileNotFoundException e) {


e.printStackTrace();


} catch (IOException e) {


e.printStackTrace();


}


}


}


[](


)工具类:组合数据类




package com.wyz.world.utils;


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(List<XWPFChart> charts,int 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(List<XWPFChart> charts,int 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(List<XWPFChart> charts, int 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(chartSeat);


/**


  • 第 N 个位置可绘制区域的图表


*/


this.ctChart = this.xwpfChart.getCTChart();


}


/**


  • 执行模板数据源填充

  • @param sheetName 展示数据 excel 页名字


*/


public void executeFillModel(String s


【一线大厂Java面试题解析+核心总结学习笔记+最新架构讲解视频+实战项目源码讲义】
浏览器打开:qq.cn.hn/FTf 免费领取
复制代码


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


}


}


/**


  • 异常校验


*/


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;


}


}


[](


)工具类:枚举解析图表类




package com.wyz.world.utils;


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.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){


/**


  • 填充模板数据

  • @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);


}


}


/**


  • 得到目标位置的图表

  • @param ctChart 可绘制区域图表

  • @param xmlObjSeat 目标图标位置位置

  • @return


*/


@Override


public XmlObject getTargetChart(int 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) {


/**


  • 填充模板数据

  • @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);


}


}


/**


  • 得到目标位置的图表

  • @param ctChart 可绘制区域图表

  • @param xmlObjSeat 目标图标位置位置

  • @return


*/


@Override


public XmlObject getTargetChart(int 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){


/**


  • 填充模板数据

  • @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();


this.dataAnalysisFill(chartModel,i,bias,cat,val);


}


}


/**


  • 得到目标位置的图表

  • @param ctChart 可绘制区域图表

  • @param xmlObjSeat 目标图标位置位置

  • @return


*/


@Override


public XmlObject getTargetChart(int chartSeat, CTChart ctChart, int xmlObjSeat) {

用户头像

极客good

关注

还未添加个人签名 2021.03.18 加入

还未添加个人简介

评论

发布
暂无评论
java使用poi操作world生成饼图,柱状图,折线图,java微服务架构训练营