poi 导出图表双Y轴组合图

有一个需求需要导出excel,但是内容需要体现图表,而且这个图表比较复杂,试过了很多框架,最后使用poi实现了。
实际导出来的效果
用到的jar包maven坐标

<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi-ooxml</artifactId>
			<version>4.1.2</version>
		</dependency>
		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi-ooxml-schemas</artifactId>
			<version>4.1.0</version>
		</dependency>
		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>ooxml-schemas</artifactId>
			<version>1.4</version>
		</dependency>
		<!-- Apache POI 的核心组件 -->
		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi</artifactId>
			<version>4.1.2</version> <!-- 请替换为当前最新的稳定版本 -->
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
	<!--2.poi官网指出需要poi4.x.x版本抛弃了jdk1.7之前的版本,所以适应此版本需要将jdk升级,如果不想升级还有另一种办法就是,使用springBoot单独做一个服务为你的主项目提供一个接口,让主项目去调用生成word流让主项目去接收即可。-->

		<dependency>
			<groupId>commons-lang</groupId>
			<artifactId>commons-lang</artifactId>
			<version>2.6</version>
		</dependency>


		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
			<version>3.5</version>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
					<scope>test</scope>
		</dependency>

测试类



import cn.hutool.core.io.FileUtil;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xddf.usermodel.PresetColor;
import org.apache.poi.xddf.usermodel.XDDFColor;
import org.apache.poi.xddf.usermodel.XDDFSolidFillProperties;
import org.apache.poi.xddf.usermodel.chart.*;
import org.apache.poi.xssf.usermodel.*;
import org.assertj.core.util.Lists;
import org.junit.jupiter.api.Test;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


public class DemoApplicationAITest {
 @Test
    public  void test() throws Exception {
        XSSFWorkbook wb = new XSSFWorkbook();
        String sheetName = "Sheet1";
        FileOutputStream fileOut = null;
        try {
            XSSFSheet sheet = wb.createSheet(sheetName);
            List<String> testList = new ArrayList<String>();
            testList.add("2024-05-15");
            testList.add("2024-05-16");
            testList.add("2024-05-17");
            testList.add("2024-05-18");
            testList.add("2024-05-19");
            testList.add("2024-05-20");
            testList.add("2024-05-21");

            List<Integer> areaList = new ArrayList<Integer>();
            // 第二行,测试值
            areaList.add(10);
            areaList.add(90);
            areaList.add(98);
            areaList.add(95);
            areaList.add(85);
            areaList.add(77);
            areaList.add(32);
            List<Integer> areaList1 = new ArrayList<Integer>();
               // 第二行,测试值
            areaList2.add(15);
            areaList2.add(83);
            areaList2.add(35);
            areaList2.add(72);
            areaList2.add(16);
            areaList2.add(99);
            areaList2.add(32);
            //内存中添加数据
            initDataTable(wb, sheet, testList, areaList, areaList1, areaList2);
            //创建一个画布
            XSSFDrawing drawing = sheet.createDrawingPatriarch();
            //前四个默认0,[0,10]:从0列10行开始;[10,30]:宽度10个单元格,30向下扩展到30行
   XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 10, 10, 20, 30);
            //创建一个chart对象
            XSSFChart chart = drawing.createChart(anchor);
            //标题
            chart.setTitleText("测试标题");
            //标题覆盖
            chart.setTitleOverlay(false);
            //图例位置
            XDDFChartLegend legend = chart.getOrAddLegend();
            legend.setPosition(LegendPosition.TOP_RIGHT);
          XDDFDataSource<String> countries = XDDFDataSourcesFactory.fromStringCellRange(sheet, new CellRangeAddress(0, 0, 1, 7));
            XDDFNumericalDataSource<Double> area = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(1, 1, 1, 7));
            XDDFNumericalDataSource<Double> area1 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(2, 2, 1, 7));
          XDDFNumericalDataSource<Double> area2 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(3, 3, 1, 7));


            //分类轴标(X轴),标题位置
            XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
            bottomAxis.setTitle("X轴标题");
            bottomAxis.setCrosses(AxisCrosses.MIN);
            //值(Y轴)轴,标题位置
            XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
            leftAxis.setTitle("Y轴标题");
       leftAxis.setCrosses(AxisCrosses.MIN);
            leftAxis.setCrossBetween(AxisCrossBetween.BETWEEN);

            XDDFBarChartData bar = (XDDFBarChartData) chart.createData(ChartTypes.BAR, bottomAxis, leftAxis);
            XDDFBarChartData.Series series1 = (XDDFBarChartData.Series) bar.addSeries(countries, area);
            bar.setBarDirection(BarDirection.COL);
            series1.setTitle("测试", null);
          XDDFBarChartData.Series series2 = (XDDFBarChartData.Series) bar.addSeries(countries, area1);
            series2.setTitle("测试1", null);
            chart.plot(bar);

            XDDFValueAxis leftAxis1 = chart.createValueAxis(AxisPosition.RIGHT);
            leftAxis1.setTitle("第二条Y轴标题");
            leftAxis1.setCrossBetween(AxisCrossBetween.BETWEEN);
            leftAxis1.setCrosses(AxisCrosses.MAX);
            leftAxis1.crossAxis(bottomAxis);
              bottomAxis.crossAxis(leftAxis1);
            XDDFChartData data = chart.createData(ChartTypes.LINE, bottomAxis, leftAxis1);

            data.addSeries(countries, area2).setTitle("测试2",null);
            chart.plot(data);
            //
//            XDDFValueAxis leftAxis1 = chart.createValueAxis(AxisPosition.RIGHT);
//            leftAxis1.setTitle("第二条Y轴");
//            //XDDFNumericalDataSource<Double> area2 = XDDFDataSourcesFactory.fromArray(areaList2.toArray(new Double[areaList2.size()]));
//            //bar:,XDDFChartData可以看看可以实现的视图种类
//            XDDFLineChartData line = (XDDFLineChartData) chart.createData(ChartTypes.LINE, bottomAxis, leftAxis1);
//            leftAxis1.setCrosses(AxisCrosses.MAX);
//            leftAxis1.setCrossBetween(AxisCrossBetween.BETWEEN);
//            //设置为可变颜色
//            line.setVaryColors(false);
//            //条形图方向,纵向/横向:纵向
//            //bar.setBarDirection(BarDirection.COL);
//            //图表加载数据,条形图1
//            XDDFLineChartData.Series series3 = (XDDFLineChartData.Series) line.addSeries(countries, area2);
//            //条形图例标题
//            series3.setTitle("测试3", null);
            XDDFSolidFillProperties fill3 = new XDDFSolidFillProperties();
            //条形图,填充颜色
            series3.setFillProperties(fill3);
//            chart.plot(line);
//
//
//            CTPlotArea plotArea = chart.getCTChart().getPlotArea();
//            //柱状图1上显示数值
//            plotArea.getBarChartArray(0).getSerArray(0).addNewDLbls();
//            plotArea.getBarChartArray(0).getSerArray(0).getDLbls().addNewShowVal().setVal(true);
//            plotArea.getBarChartArray(0).getSerArray(0).getDLbls().addNewShowLegendKey().setVal(false);
//            plotArea.getBarChartArray(0).getSerArray(0).getDLbls().addNewShowCatName().setVal(false);
//            plotArea.getBarChartArray(0).getSerArray(0).getDLbls().addNewShowSerName().setVal(false);
//            //***** 非常重要,可以设置excel中的对应(以互补色代表负值),对于条形图有负数的情况,一定要设置,否则颜色无法填充
//            //            plotArea.getBarChartArray(0).getSerArray(0).addNewInvertIfNegative().setVal(false);
//
//            CTPlotArea plotArea1 = chart.getCTChart().getPlotArea();
//            //柱状图1上显示数值
//            plotArea1.getBarChartArray(0).getSerArray(1).addNewDLbls();
//            plotArea1.getBarChartArray(0).getSerArray(1).getDLbls().addNewShowVal().setVal(true);
//            plotArea1.getBarChartArray(0).getSerArray(1).getDLbls().addNewShowLegendKey().setVal(false);
/            plotArea1.getBarChartArray(0).getSerArray(1).getDLbls().addNewShowCatName().setVal(false);
//            plotArea1.getBarChartArray(0).getSerArray(1).getDLbls().addNewShowSerName().setVal(false);
//            //***** 非常重要,可以设置excel中的对应(以互补色代表负值),对于条形图有负数的情况,一定要设置,否则颜色无法填充
//            plotArea1.getBarChartArray(0).getSerArray(1).addNewInvertIfNegative().setVal(false);
//
    // fixChart(chart);

            System.out.println("===================");
            System.out.println(chart.getCTChart());
            System.out.println("===================");

            // 将输出写入excel文件
            String tmpFileName = "D://" + System.currentTimeMillis() + ".xlsx";
            FileUtil.file(tmpFileName);
            fileOut = new FileOutputStream(tmpFileName);
            wb.write(fileOut);
        } catch (Exception e) {
            e.printStackTrace();
         } finally {
            wb.close();
            if (fileOut != null) {
                fileOut.close();
            }
        }
     }
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
您好!对于导出Y轴四条线的需求,您可以使用POI(Apache POI)库来实现。下面是一个示例代码,可以帮助您导出Y轴四条线的图表: ```java import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.FileOutputStream; import java.io.IOException; public class DualAxisChartExample { public static void main(String[] args) { // 创建工作簿 Workbook workbook = new XSSFWorkbook(); Sheet sheet = workbook.createSheet("Dual Axis Chart"); // 创建数据 Object[][] data = { {"Category", "Value 1", "Value 2", "Value 3", "Value 4"}, {"A", 10, 20, 30, 40}, {"B", 15, 25, 35, 45}, {"C", 20, 30, 40, 50}, {"D", 25, 35, 45, 55}, {"E", 30, 40, 50, 60} }; // 写入数据 int rowNum = 0; for (Object[] rowData : data) { Row row = sheet.createRow(rowNum++); int colNum = 0; for (Object cellData : rowData) { Cell cell = row.createCell(colNum++); if (cellData instanceof String) { cell.setCellValue((String) cellData); } else if (cellData instanceof Integer) { cell.setCellValue((Integer) cellData); } } } // 创建图表 Drawing drawing = sheet.createDrawingPatriarch(); ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 5, 1, 15, 20); Chart chart = drawing.createChart(anchor); ChartLegend legend = chart.getOrCreateLegend(); legend.setPosition(LegendPosition.BOTTOM); ScatterChartData chartData = chart.getChartDataFactory().createScatterChartData(); // 创建第一个数据系列并设置Y轴 ChartAxis yAxis1 = chart.getChartAxisFactory().createValueAxis(AxisPosition.LEFT); ChartAxis yAxis2 = chart.getChartAxisFactory().createValueAxis(AxisPosition.RIGHT); // 设置Y轴标题 yAxis1.setTitle("Values 1 and 2"); yAxis2.setTitle("Values 3 and 4"); // 添加数据 for (int i = 1; i < data.length; i++) { Object[] rowData = data[i]; NumberCellValue xValue = new NumberCellValue(i); NumberCellValue yValue1 = new NumberCellValue((Integer) rowData[1]); NumberCellValue yValue2 = new NumberCellValue((Integer) rowData[2]); NumberCellValue yValue3 = new NumberCellValue((Integer) rowData[3]); NumberCellValue yValue4 = new NumberCellValue((Integer) rowData[4]); ScatterChartSeries series1 = chartData.addSerie(yAxis1, xAxis, xValue, yValue1); ScatterChartSeries series2 = chartData.addSerie(yAxis1, xAxis, xValue, yValue2); ScatterChartSeries series3 = chartData.addSerie(yAxis2, xAxis, xValue, yValue3); ScatterChartSeries series4 = chartData.addSerie(yAxis2, xAxis, xValue, yValue4); // 设置系列名称 series1.setTitle("Series 1"); series2.setTitle("Series 2"); series3.setTitle("Series 3"); series4.setTitle("Series 4"); } // 将图表绑定到画布上 chart.plot(chartData); // 保存工作簿 try (FileOutputStream outputStream = new FileOutputStream("DualAxisChart.xlsx")) { workbook.write(outputStream); } catch (IOException e) { e.printStackTrace(); } } } ``` 这段代码使用了Apache POI库来创建一个Excel文件,并在其中添加了Y轴四条线的散点图表,然后将工作簿保存为"DualAxisChart.xlsx"文件。 请注意,您需要将Apache POI库添加到您的项目依赖中,以便能够成功编译和运行上述代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值