Java Apache POI 创建 Excel 双坐标轴折线图
Java Apache POI 创建 Excel 双坐标轴折线图
本文介绍如何使用 Java 和 Apache POI 库创建带有双坐标轴的 Excel 折线图。
代码示例javaimport org.apache.poi.ss.usermodel.;import org.apache.poi.ss.util.CellRangeAddress;import org.apache.poi.xddf.usermodel.chart.;import org.apache.poi.xssf.usermodel.*;import org.openxmlformats.schemas.drawingml.x2006.chart.CTBoolean;import org.openxmlformats.schemas.drawingml.x2006.chart.CTLineSer;
import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.text.SimpleDateFormat;import java.util.Date;
public class ExcelChartExample04 {
public static void main(String[] args) { try { // 读取Excel文件 FileInputStream fileIn = new FileInputStream('input-1.xlsx'); XSSFWorkbook workbook = new XSSFWorkbook(fileIn); XSSFSheet sheet1 = workbook.getSheet('P1');
// 创建折线图 XSSFDrawing drawing = sheet1.createDrawingPatriarch(); XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 129, 10, 149); XDDFChart chart = drawing.createChart(anchor); chart.setTitleText('数据折线图'); chart.setTitleOverlay(false);
// 设置图例位置 XDDFChartLegend legend = chart.getOrAddLegend(); legend.setPosition(LegendPosition.BOTTOM);
// 设置横坐标轴为日期坐标轴 XDDFDataSource<?> dateSource = XDDFDataSourcesFactory.fromArray(new String[] {'A2:A127'}); XDDFDateAxis bottomAxis = chart.createDateAxis(AxisPosition.BOTTOM); bottomAxis.setCrosses(AxisCrosses.AUTO_ZERO); bottomAxis.setTitle('时间'); bottomAxis.setTickLabelPosition(AxisTickLabelPosition.NEXT_TO);
// 设置时间格式 SimpleDateFormat dateFormat = new SimpleDateFormat('yyyy/MM/dd'); for (int i = 0; i < dateSource.getPointCount(); i++) { Row row = sheet1.getRow(i + 1); if (row != null) { Cell cell = row.getCell(0); if (cell != null && cell.getCellType() == CellType.NUMERIC) { Date date = cell.getDateCellValue(); String formattedDate = dateFormat.format(date); cell.setCellValue(formattedDate); } } }
// 设置左侧坐标轴为温度坐标轴 XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT); leftAxis.setCrosses(AxisCrosses.AUTO_ZERO); leftAxis.setTitle('温度');
// 设置右侧坐标轴为数值坐标轴 XDDFValueAxis rightAxis = chart.createValueAxis(AxisPosition.RIGHT); rightAxis.setCrosses(AxisCrosses.MAX); rightAxis.setTitle('数据值');
// 设置数据源 XDDFNumericalDataSource<Double> xs1 = XDDFDataSourcesFactory.fromNumericCellRange(sheet1, new CellRangeAddress(1, 127, 2, 2)); XDDFNumericalDataSource<Double> ys1 = XDDFDataSourcesFactory.fromNumericCellRange(sheet1, new CellRangeAddress(1, 127, 0, 0)); XDDFNumericalDataSource<Double> ys2 = XDDFDataSourcesFactory.fromNumericCellRange(sheet1, new CellRangeAddress(1, 127, 1, 1));
// 添加数据系列 XDDFLineChartData data = (XDDFLineChartData) chart.createData(ChartTypes.LINE, bottomAxis, leftAxis); XDDFLineChartData.Series series1 = (XDDFLineChartData.Series) data.addSeries(xs1, ys1); series1.setTitle('折线图1', null); series1.setSmooth(false); series1.setMarkerStyle(MarkerStyle.NONE);
// 添加第二个数据系列 XDDFLineChartData.Series series2 = (XDDFLineChartData.Series) data.addSeries(xs1, ys2); series2.setTitle('折线图2', null); series2.setSmooth(false); chart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(1).getOrder().setVal(1);
// 设置次要垂直坐标轴 CTBoolean ctBoolean = CTBoolean.Factory.newInstance(); ctBoolean.setVal(false); CTLineSer ctLineSer = chart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(1); ctLineSer.addNewDLbls(); ctLineSer.getDLbls().setShowLegendKey(ctBoolean); ctLineSer.getDLbls().setShowVal(ctBoolean); ctLineSer.getDLbls().setShowCatName(ctBoolean); ctLineSer.getDLbls().setShowSerName(ctBoolean);
// 保存Excel文件 FileOutputStream fileOut = new FileOutputStream('input-1.xlsx'); workbook.write(fileOut); fileOut.close();
System.out.println('折线图已创建并保存到Excel文件中。');
} catch (IOException e) { e.printStackTrace(); } }}
问题解决
在设置次要垂直坐标轴时,可能会遇到 NullPointerException 错误,这是因为 DLbls 对象为空。解决方法是在调用 getDLbls() 方法之前,先创建一个新的 DLbls 对象:java// 设置次要垂直坐标轴CTBoolean ctBoolean = CTBoolean.Factory.newInstance();ctBoolean.setVal(false);CTLineSer ctLineSer = chart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(1);ctLineSer.addNewDLbls(); // 创建新的 DLbls 对象ctLineSer.getDLbls().setShowLegendKey(ctBoolean);ctLineSer.getDLbls().setShowVal(ctBoolean);ctLineSer.getDLbls().setShowCatName(ctBoolean);ctLineSer.getDLbls().setShowSerName(ctBoolean);
总结
本文介绍了如何使用 Java 和 Apache POI 库创建带有双坐标轴的 Excel 折线图,并提供了解决常见问题的代码示例。希望对您有所帮助!
原文地址: https://www.cveoy.top/t/topic/fSEc 著作权归作者所有。请勿转载和采集!