说明

动态创建带有多个图表的Excel文件


效果图:

一、分析

第一种:创建图表模板,在Excel模板里设置好图表,然后通过更新模板数值,最终刷新图表;(也包含刷新图标各项数据)
第二种:动态创建带有数值与图表的Excel

说明:第一种,有一定的局限性,就是Excel里的数值与图表的格式需要固定,只是对数值进行替换。实际开发过程中,很少有固定的格式,所以重点讲解第二种;

二、全动态导出Excel带有多个图表–》实现步骤

第一步:根据传入的数据集,生成数据表的表头与数据行,并返回创建画布XSSFDrawing
第二步:在画布里创建空图表XSSFChart
第三步:设置图表XSSFChart,比如:创建柱状图
第四步:生成导出Excel文件

1.根据传入的数据集,生成数据表的表头与数据行

创建数据源,就是创建列头,数据行以及样式等;
一个sheet对应一个画布,所有返回一个画布;
代码如下:

private XSSFDrawing createXSSFDrawingBuildDataSource(ExcelMoreDataSourceInput input) {if (Objects.isNull(wb)) wb = new XSSFWorkbook();XSSFSheet sheet = wb.createSheet(input.getSheetName());// 创建数据源drawTable(sheet, input.getTitleArr(), input.getFldNameArr(), input.getDataList());// 创建一个画布return sheet.createDrawingPatriarch();}

2.在画布里创建空图表XSSFChart

在画布里创建空图表XSSFChart,设置第几行几列为图表(多个图表布局好即可)
代码如下:

    /*** 创建图表** @param isPutOnRight 比如:当列数大于5时,把画布放在数组右边* @param chartNum     创建第几个图表*/private XSSFChart createChart(XSSFDrawing drawing, int cols, int rows, boolean isPutOnRight, int chartNum) {int colNum = 25;ClientAnchor anchor;if (isPutOnRight) {anchor = drawing.createAnchor(0, 0, 0, 0, 1, rows + 2 + colNum * (chartNum - 1), cols + 15, rows + colNum * chartNums);} else {anchor = drawing.createAnchor(0, 0, 0, 0, cols + 1, 4 + colNum * (chartNum - 1), cols + 15, colNum * chartNums);}// 创建一个chart对象return drawing.createChart(anchor);}

3.设置图表XSSFChart

以制作柱状图为例:
1、确认哪些列作为图例项
2、设置横坐标,这里固定第一列为横坐标
3、设置数据区域范围
具体请看一下代码
代码如下:

    /*** 生成柱状图** @param chart           图表* @param group           柱状图类型(堆积,多组)* @param fldNameArrIndex 数据列下标(用于Excel标识数据源区域)* @param rows            数据行数* @param sheetName       sheet的名称*/private void drawBarChartMap(XSSFChart chart, STBarGrouping.Enum group, int[] fldNameArrIndex, int rows, String sheetName) {CTChart ctChart = chart.getCTChart();CTPlotArea ctPlotArea = ctChart.getPlotArea();// 创建柱状图模型CTBarChart ctBarChart = ctPlotArea.addNewBarChart();CTBoolean ctBoolean = ctBarChart.addNewVaryColors();ctBarChart.getVaryColors().setVal(true);// 设置图类型ctBarChart.addNewGrouping().setVal(group);ctBoolean.setVal(true);ctBarChart.addNewBarDir().setVal(STBarDir.COL);// 是否添加左侧坐标轴ctChart.addNewDispBlanksAs().setVal(STDispBlanksAs.ZERO);ctChart.addNewShowDLblsOverMax().setVal(true);// 设置这两个参数是为了在STACKED模式下生成堆积模式;(standard)标准模式时需要将这两行去掉if ("stacked".equals(group.toString()) || "percentStacked".equals(group.toString())) {ctBarChart.addNewGapWidth().setVal(150);ctBarChart.addNewOverlap().setVal((byte) 100);}// 创建序列,并且设置选中区域for (int i = 0; i < fldNameArrIndex.length; i++) {int col = fldNameArrIndex[i];CTBarSer ctBarSer = ctBarChart.addNewSer();CTSerTx ctSerTx = ctBarSer.addNewTx();// 图例区CTStrRef ctStrRef = ctSerTx.addNewStrRef();// 选定区域第0行,第1,2,3列标题作为图例 //1 2 3String legendDataRange = new CellRangeAddress(0, 0, col, col).formatAsString(sheetName, true);ctStrRef.setF(legendDataRange);ctBarSer.addNewIdx().setVal(i);// 横坐标区CTAxDataSource cttAxDataSource = ctBarSer.addNewCat();ctStrRef = cttAxDataSource.addNewStrRef();// 选第0列为横坐标区域String axisDataRange = new CellRangeAddress(1, rows, 0, 0).formatAsString(sheetName, true);ctStrRef.setF(axisDataRange);// 数据区域CTNumDataSource ctNumDataSource = ctBarSer.addNewVal();CTNumRef ctNumRef = ctNumDataSource.addNewNumRef();// 选第1-6行,第1-3列作为数据区域 //1 2 3String numDataRange = new CellRangeAddress(1, rows, col, col).formatAsString(sheetName,true);ctNumRef.setF(numDataRange);// 添加柱状边框线ctBarSer.addNewSpPr().addNewLn().addNewSolidFill().addNewSrgbClr().setVal(new byte[]{0, 0, 0});// 设置负轴颜色不是白色ctBarSer.addNewInvertIfNegative().setVal(false);// 设置标签格式ctBoolean.setVal(false);CTDLbls newDLbls = ctBarSer.addNewDLbls();newDLbls.setShowLegendKey(ctBoolean);ctBoolean.setVal(true);newDLbls.setShowVal(ctBoolean);ctBoolean.setVal(false);newDLbls.setShowCatName(ctBoolean);newDLbls.setShowSerName(ctBoolean);newDLbls.setShowPercent(ctBoolean);newDLbls.setShowBubbleSize(ctBoolean);newDLbls.setShowLeaderLines(ctBoolean);}// 告诉BarChart它有坐标轴,并给它们idctBarChart.addNewAxId().setVal(123456);ctBarChart.addNewAxId().setVal(123457);// 横坐标CTCatAx ctCatAx = ctPlotArea.addNewCatAx();ctCatAx.addNewAxId().setVal(123456); // id of the cat axisCTScaling ctScaling = ctCatAx.addNewScaling();ctScaling.addNewOrientation().setVal(STOrientation.MIN_MAX);ctCatAx.addNewAxPos().setVal(STAxPos.B);ctCatAx.addNewCrossAx().setVal(123457); // id of the val axisctCatAx.addNewTickLblPos().setVal(STTickLblPos.NEXT_TO);// 纵坐标CTValAx ctValAx = ctPlotArea.addNewValAx();ctValAx.addNewAxId().setVal(123457); // id of the val axisctScaling = ctValAx.addNewScaling();ctScaling.addNewOrientation().setVal(STOrientation.MIN_MAX);// 设置位置ctValAx.addNewAxPos().setVal(STAxPos.L);ctValAx.addNewCrossAx().setVal(123456); // id of the cat axisctValAx.addNewTickLblPos().setVal(STTickLblPos.NEXT_TO);// 是否删除主左边轴ctValAx.addNewDelete().setVal(false);// 是否删除横坐标ctCatAx.addNewDelete().setVal(false);// legend图注// if(true){CTLegend ctLegend = ctChart.addNewLegend();ctLegend.addNewLegendPos().setVal(STLegendPos.B);ctLegend.addNewOverlay().setVal(false);// }}

4.生成导出Excel文件

代码如下:

    public void createTpl(String filePath) {try {File f = new File(filePath); //写文件//不存在则新增if (!f.getParentFile().exists()) {f.getParentFile().mkdirs();}if (!f.exists()) {f.createNewFile();}FileOutputStream out = new FileOutputStream(f);out.flush();wb.write(out);out.close();} catch (IOException e) {e.printStackTrace();}

三、测试用例

/*** 根据数据源,生成多个图表*/
public class ExcelChartUtilTest {@Testpublic void excelChartTest() {// 字段名List<String> fldNameArr = new ArrayList<>();fldNameArr.add("value1");fldNameArr.add("value2");fldNameArr.add("value3");fldNameArr.add("value4");// 列头List<String> titleArr = new ArrayList<>();titleArr.add("类型");titleArr.add("总额");titleArr.add("数量");titleArr.add("人均");// 模拟数据List<Map<String, Object>> dataList = new ArrayList<>();for (int i = 0; i < 10; i++) {Map<String, Object> dataMap_ = new HashMap<>();dataMap_.put("value1", "类型" + i);dataMap_.put("value2", Math.floor(Math.random() * 100) + "");dataMap_.put("value3", i);dataMap_.put("value4", Math.floor(Math.random() * 10));dataList.add(dataMap_);}//开始赋值ExcelMoreDataSourceInput input = new ExcelMoreDataSourceInput();input.setTitleArr(titleArr);input.setFldNameArr(fldNameArr);input.setDataList(dataList);// 固定第一列为横坐标区域List<ChartDataSource> chartDataSources = Lists.newArrayList();ChartDataSource dataSource = new ChartDataSource();dataSource.setChartType(ChartType.LINE);dataSource.setLegendItems(Lists.newArrayList("value2"));ChartDataSource dataSource1 = new ChartDataSource();dataSource1.setChartType(ChartType.BAR);dataSource1.setLegendItems(Lists.newArrayList("value2", "value3", "value4"));chartDataSources.add(dataSource);chartDataSources.add(dataSource1);input.setChartDataSources(chartDataSources);ExcelChartMoreUtil moreUtil = new ExcelChartMoreUtil(input);String pathName = "C:/file/chart/chartMore.xlsx";moreUtil.createTpl(pathName);}
}

根据模板生成图标(更新数值,从而刷新图标)

模板内容:

执行测试方法后,效果图下:

代码如下:

@Testpublic void chart_fixed_row_column_test() throws Exception {final String fileInput = "C:\\file\\chart\\test\\line-chart-template-test.xlsx";try (FileInputStream argIS = new FileInputStream(fileInput)) {try (XSSFWorkbook xssfWorkbook = new XSSFWorkbook(argIS)) {//获取创建工作簿的第一页XSSFSheet sheet = xssfWorkbook.getSheetAt(0);//自动计算sheet.setForceFormulaRecalculation(true);//给指定的sheet命名xssfWorkbook.setSheetName(0, "sheet0");//初始化当前的索引,设为当前sheet的最后一行行数int allRows = sheet.getLastRowNum();//填充数据for (int i = 1; i <= allRows; i++) {XSSFRow row = sheet.getRow(i);if (row == null) {continue;}//遍历列for (int j = 0; j < 4; j++) {XSSFCell cell = row.getCell(j) != null ? row.getCell(j) : row.createCell(j);String cellValue = cell.getStringCellValue();if (cellValue.startsWith("#")) {if (j == 0) cell.setCellValue("岗位" + i);else cell.setCellValue(i * 10 + j);}}// 保存返回try (OutputStream out = new FileOutputStream("C:\\file\\chart\\test\\line_chart-demo-output.xlsx")) {xssfWorkbook.write(out);}}}}}

Excel导出带有多个图表(柱状图、折线图、饼状图等)相关推荐

  1. java导出pdf报告之六:使用jfreechart生成饼状图和柱状图

    关于使用jfreechart生成饼状图和柱状图网上也有一大推,我在这里也不做太多介绍,就直接附上我的实现,并添加了一下注释,供大家参考. 生成饼状图: /*** @param name 图片的名称* ...

  2. MPAndroidChart 折线图 饼状图 条形图 最简单使用方式(kotlin)

    首先,我是一个小白,最近做安卓,突然碰到需要做一个饼状图 一个折线图 一个条形图显示出来,没有什么要求,只要能显示出来就可以,既然这样的话,那我就需要找到这三个图最简单的实现方式,发现使用MPAndr ...

  3. canvas制作柱形图/折线图/饼状图,Konva写动态饼状图

    制作饼状图 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...

  4. Qt绘制柱状图BarChart、饼状图PieChart、堆叠柱状图StackedChart、散点图ScatterChart

    一.效果展示 二.工程中添加charts模块 三.在工程布局文件中放一块Graphics View,然后右键提升为QChartView,每个Tab都一样.如下图 四.更改控件名,如下图所示 五.Mai ...

  5. Poi 如何使用Java和POI技术生成折线图,柱状图,饼状图导出到word文档

    这篇文章主要介绍POI生成图表并导出word文档的基本操作.主要介绍三种图表:折线图.柱状图.饼状图. 一.效果展示 使用Java和POI技术生成的折线图,柱状图,饼状图的效果如下图所示: 二.环境准 ...

  6. Flutter 饼状图、柱状图、拆线图、Flutter动态饼图、Flutter图表 flutter_echart 开发文档

    在码农的世界里,优美的应用体验,来源于程序员对细节的处理以及自我要求的境界,年轻人也是忙忙碌碌的码农中一员,每天.每周,都会留下一些脚印,就是这些创作的内容,有一种执着,就是不知为什么,如果你迷茫,不 ...

  7. python中输出手机话费_用Python生成柱状图、折线图、饼状图来统计自己的手机话费...

    环境 macOS PyCharm 依赖库 matplotlib numpy 中文字体 步骤详解 一.配置依赖包 使用pycharm,直接依赖 matplotlib,如果当前环境变量的pip中不包含 m ...

  8. VC++操作Excel生成饼状图!

    因为需要通过MFC实现自动生成Excel文件,并且实现数据饼状图的效果,搜索全网只找到生成柱状图的程序模板,怎么改都会显示错误,后来通过Excel宏的录制和编辑弄明白了饼状图的做法(其他图形类似) c ...

  9. java 生成柱状图、饼状图等图片保存至word文档

    写在前面,springboot pom 中引入下面就可以了,省了在csdn找包很麻烦. <dependency><artifactId>jfreechart</artif ...

最新文章

  1. Java测试List<Object>根据其某个属性去重俩种方法效率
  2. Nature调查:6%中国科研人年薪超50万元!
  3. [转]Hyper-V功能大跃进 或引发市场洗牌
  4. java 按钮键盘,java中关于键盘代替按钮的一些有关问题(是代替)~
  5. python变量 数据类型 列表 元组 字典
  6. 信息学奥赛一本通C++语言——1020: 打印ASCII码
  7. 微服务容错时,这些技术你要立刻想到
  8. 湿气重的人,脸上会有哪些信号?
  9. 在React中测试和调试
  10. 婚纱摄影五大标杆品牌告诉你,客资转化居然可以这么玩?
  11. Python之认识世界
  12. 树莓派安装qq linux,在(Raspberry Pi)树莓派上安装NodeJS
  13. 花了一年时间开发的铣床数控系统NCStudioPro(支持钻孔,铣削,切割等铣床加工工艺)...
  14. java共享汽车租赁系统
  15. 【mpeg4】xvid参数分析
  16. CentOS7安装FTP服务器及默认21端口修改
  17. python就业方向有哪些?
  18. CryptoJS加密库使用及bug解决
  19. 托业阅读时间怎么安排【zhasite】
  20. shell中用grep查找并且不输出_grep无法查找shell传过来的变量?先注意一下文本格式吧!...

热门文章

  1. org.apache.commons.codec.binary.Base64包需要下载的jar包依赖
  2. 车载、行车记录仪产品知识汇集
  3. cocos2dx之音效引擎
  4. C语言—超长正整数的乘法实现简洁版
  5. iOS-百度语音识别
  6. linux中将文本中的单词换掉的指令_干货:Linux常用命令全称及讲解
  7. 中国大学MOOC数据库系统概论中国人民大学实验三 触发器
  8. Delong test比较两个ROC曲线的性能
  9. LaTeX入门教程|自定义论文标题
  10. 上次被 ArrayList 锤了一拳后,LinkedList 很不服气,做出最后一击