我已经开始使用Apache POI来创建一个包含图表的Excel表。 该图表使用的数据非常简单,一个日期列和一个数值列。 我想按日期的反向顺序显示数据,这样最新的数据就会在电子表格的最上面一行,但我希望图表能按正常的日期顺序显示数据,因为我还包括一条趋势线,而趋势线的方向完全取决于数据的顺序。 日期显示在x轴上,y轴包含数值。 我想做的是将图表上的所有数据反过来。 有什么方法可以做到这一点吗? 在Google Sheets中,它是自动发生的,但这不是一个选项.这是我目前正在试验的代码。
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轴的标签现在出现在右边而不是左边,但我想我可以接受。