1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > Excel导出带有多个图表(柱状图 折线图 饼状图等)

Excel导出带有多个图表(柱状图 折线图 饼状图等)

时间:2019-01-01 11:36:56

相关推荐

Excel导出带有多个图表(柱状图 折线图 饼状图等)

说明

动态创建带有多个图表的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);}}}}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。