java - Apache POI 图表与日期

标签 java excel graph apache-poi

我已开始使用 Apache POI 创建包含图表的 Excel 工作表。该图表使用非常简单的数据,即日期列和数值列。我想以日期相反的顺序显示数据,以便最新数据位于电子表格的顶行,但我希望图表以日期正常顺序显示数据,因为我还包括一条趋势线,并且趋势线的方向完全取决于数据的排序。日期显示在 x 轴上,y 轴包含数值。我想做的基本上就是反转图表上的所有数据。有什么方法可以做到这一点吗?在 Google 表格中,它会自动发生,但这不是一个选项。 这是我当前正在试验的代码:

public void addChart() {
    final int NUM_OF_ROWS = ytd.size();
    final int NUM_OF_COLUMNS = 2;

    // Create a row and put some cells in it. Rows are 0 based.
    XSSFRow row;
    XSSFCell cell;
    List<String> dates = new ArrayList<>();
    List<Double> values = new ArrayList<>();
    for (int rowIndex = 0; rowIndex < NUM_OF_ROWS; rowIndex++) {
        row = (XSSFRow)sheet.createRow((short) rowIndex);
        row.createCell(0).setCellValue(ytd.get(rowIndex).getShipDate());
        dates.add(ytd.get(rowIndex).getShipDate());
        for (int colIndex = 1; colIndex < NUM_OF_COLUMNS; colIndex++) {
            cell = row.createCell((short) colIndex);
            cell.setCellValue(new BigDecimal(ytd.get(rowIndex).getSquareFeet().replaceAll("[,]", "")).doubleValue());
            values.add(new BigDecimal(ytd.get(rowIndex).getSquareFeet().replaceAll("[,]", "")).doubleValue());
        }
    }
    Collections.reverse(dates);
    Collections.reverse(values);
    for (int rowIndex = 0; rowIndex < NUM_OF_ROWS; rowIndex++) {
        row = sheet.getRow((short) rowIndex);
        row.createCell(2).setCellValue(dates.get(rowIndex));
        for (int colIndex = 3; colIndex < 4; colIndex++) {
            cell = row.createCell((short) colIndex);
            cell.setCellValue(values.get(rowIndex));
        }
    }


    XSSFDrawing drawing = (XSSFDrawing) sheet.createDrawingPatriarch();
    XSSFClientAnchor anchor = drawing.createAnchor(5, 5, 20, 20, 4, 4, 20, 25);

    XSSFChart chart = drawing.createChart(anchor);
    CTChart ctChart = ((XSSFChart) chart).getCTChart();
//        XSSFChart chart = drawing.createChart(anchor);
    XDDFChartLegend legend = chart.getOrAddLegend();
    legend.setPosition(LegendPosition.TOP_RIGHT);

    // Use a category axis for the bottom axis.
    XDDFDateAxis bottomAxis = chart.createDateAxis(AxisPosition.BOTTOM);
    bottomAxis.setTitle("Ship Date"); // https://stackoverflow.com/questions/32010765
    XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
    leftAxis.setTitle("Square Feet");
    leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);

    XDDFDataSource<Double> xs = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(0,  NUM_OF_ROWS - 1, 2, 2));
    XDDFNumericalDataSource<Double> ys1 = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(0, NUM_OF_ROWS-1, 3, 3));

    XDDFLineChartData data = (XDDFLineChartData) chart.createData(ChartTypes.LINE, bottomAxis, leftAxis);
    XDDFLineChartData.Series series1 = (XDDFLineChartData.Series) data.addSeries(xs, ys1);
    series1.setTitle("SqFt", null); // https://stackoverflow.com/questions/21855842
    series1.setSmooth(false); // https://stackoverflow.com/questions/29014848
    series1.setMarkerStyle(MarkerStyle.DOT); // https://stackoverflow.com/questions/39636138
    chart.plot(data);
//        sheet.setColumnHidden(2, true);
//        sheet.setColumnHidden(3, true);

    // if your series have missing values like https://stackoverflow.com/questions/29014848
    // chart.displayBlanksAs(DisplayBlanks.GAP);
    // https://stackoverflow.com/questions/24676460
    solidLineSeries(data, 0, PresetColor.CHARTREUSE);
//        solidLineSeries(data, 1, PresetColor.TURQUOISE);
    chart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(0)
            .addNewTrendline()
            .addNewTrendlineType()
            .setVal(org.openxmlformats.schemas.drawingml.x2006.chart.STTrendlineType.LINEAR);

    // Write the output to a file
    try (FileOutputStream fileOut = new FileOutputStream("ooxml-line-chart.xlsx")) {
        workbook.write(fileOut);
    } catch (FileNotFoundException ex) {
        Exceptions.printStackTrace(ex);
    } catch (IOException ex) {
        Exceptions.printStackTrace(ex);
    }
}

我尝试将数据放入隐藏的列中,这在 LibreOffice 中工作正常,但在 Excel 中不起作用,直到我取消隐藏列。那么有谁知道是否有一种方法可以控制图形数据的顺序,与表中的数据分开?

最佳答案

我找到了解决方案:您可以通过使用枚举 AxisOrientation 修改图表上的类别轴来更改数据的方向。按照我想要的顺序将数据绘制到图表中的一个副作用是 y 轴的标签现在显示在右侧而不是左侧,但我认为我可以接受这一点。

关于java - Apache POI 图表与日期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62174602/

相关文章:

java - Java 中的单独链接

php - Facebook:连接到应用程序后获取用户拇指图像 URL

C++ 在图中查找入度为零的节点

excel - R 中多个变量的分组

Excel 条件数据和文本处理

excel - 有没有办法命名幻灯片 - 并通过这个名称而不是幻灯片索引来选择幻灯片?

c - 如何检查图表中的循环?

java - 您可以使用泛型进行方法重载并且只更改方法签名的泛型类型吗?

java - 在 eclipse 项目中实现嵌入式 Derby 数据库时出现问题?

java - 在android studio中获取以前的代码