Как изменить метку графика в apache poi? - PullRequest
0 голосов
/ 17 января 2020

Сейчас я пытаюсь изменить следующие метки из существующего .xlsx

Графическое изображение: Graph Image

График уже изменен их формулы и значения для тех, которые я хочу, но эти числа по-прежнему получают свои значения из предыдущих значений на графике. Как я могу изменить их? Я искал предыдущие вопросы, и, предположительно, метод, используемый для получения текущих значений меток (до их изменения) будет следующим:

drawing.getCharts().get(0).getCTChart().getPlotArea().getLineChartList().get(0).getSerList().get(2).getVal().getNumRef().getNumCache()

Полученный чертеж следующий из моего листа:

 XSSFDrawing drawing = sheet.createDrawingPatriarch();

Но я получаю список с 107 значениями ... Так что я не уверен, правильно это или нет. Я не знаю, что мне нужно изменить. Буду признателен за помощь.

Минимальный пример того, как я изменил график:

Этот лист Excel содержит пять списков серии с формулой, основанной на других листах Excel. Поэтому я сделал следующий код:

 drawing.getCharts().get(0).getCTChart().getPlotArea().getLineChartList().get(0).getSerList().get(0).getVal().getNumRef().setF("PERD_POLICY!$S$15:$S$" + lineasPerdPolicy + "");
    drawing.getCharts().get(0).getCTChart().getPlotArea().getLineChartList().get(0).getSerList().get(0).getCat().getNumRef().setF("PERD_POLICY!$Q$15:$Q$" + lineasPerdPolicy);

    drawing.getCharts().get(0).getCTChart().getPlotArea().getLineChartList().get(0).getSerList().get(1).getVal().getNumRef().setF("PERD_POLICY!$T$15:$T$" + lineasPerdPolicy);      
    drawing.getCharts().get(0).getCTChart().getPlotArea().getLineChartList().get(0).getSerList().get(1).getCat().getNumRef().setF("PERD_POLICY!$Q$15:$Q$" + lineasPerdPolicy);

    drawing.getCharts().get(0).getCTChart().getPlotArea().getLineChartList().get(0).getSerList().get(2).getVal().getNumRef().setF("PERD_POLICY!$U$15:$U$" + lineasPerdPolicy);
    drawing.getCharts().get(0).getCTChart().getPlotArea().getLineChartList().get(0).getSerList().get(2).getCat().getNumRef().setF("PERD_POLICY!$Q$15:$Q$" + lineasPerdPolicy);

    drawing.getCharts().get(0).getCTChart().getPlotArea().getLineChartList().get(0).getSerList().get(3).getVal().getNumRef().setF("PERD_POLICY!$V$15:$V$" + lineasPerdPolicy);
    drawing.getCharts().get(0).getCTChart().getPlotArea().getLineChartList().get(0).getSerList().get(3).getCat().getNumRef().setF("PERD_POLICY!$Q$15:$Q$" + lineasPerdPolicy);

    drawing.getCharts().get(0).getCTChart().getPlotArea().getLineChartList().get(0).getSerList().get(4).getVal().getNumRef().setF("PERD_POLICY!$W$15:$W$" + lineasPerdPolicy);
    drawing.getCharts().get(0).getCTChart().getPlotArea().getLineChartList().get(0).getSerList().get(4).getCat().getNumRef().setF("PERD_POLICY!$Q$15:$Q$" + lineasPerdPolicy);

    drawing.getCharts().get(0).getCTChart().getPlotArea().getLineChartList().get(0).getSerList().get(5).getVal().getNumRef().setF("PERD_POLICY!$R$15:$R$" + lineasPerdPolicy);
    drawing.getCharts().get(0).getCTChart().getPlotArea().getLineChartList().get(0).getSerList().get(5).getCat().getNumRef().setF("PERD_POLICY!$Q$15:$Q$" + lineasPerdPolicy);

lineasPerdPolicy - это переменная, которую я использовал для подсчета последней строки в листе, из которого мы получаем значения. Лист "PERD_POLICY". Этот график основан на месяцах от года. Теперь я добавил в текущий список serList новое значение до декабря 2019 года. Но последняя метка зеленого графика показывает 9,66. Это значение за октябрь 2019 года.

Я думаю, вы получите его лучше с помощью следующих изображений. Это показывает, каково значение последней метки:

Текущее значение метки

И выбранное значение на этом другом рисунке - это то, которое я хочу показать в 9,75

Значение графика, которое я хочу показать на этикетке

Если вы не понимаете ни одного слова, пожалуйста, дайте Я знаю, потому что мой Excel в испанском sh. Доблесть -> Значение Пунто -> Точка

1 Ответ

1 голос
/ 17 января 2020

Ваш код, использующий классы низкого уровня ooxml-schemas, обновляет только справочные формулы серии. Он не обновляет кэшированные значения в диаграмме.

Поскольку текущий apache poi 4.1.1 предоставляет XDDFChartData.Series.replaceData для обновления данных диаграммы, мы должны использовать это вместо низкого уровня ooxml-schemas классы.

Давайте разберем полный пример, чтобы показать, как это сделать.

Мы начинаем с ExcelWithChartMar.xlsx, который выглядит примерно так:

enter image description here

Как вы видите, есть данные графика в A1:D4 за месяцы с января по март уже и график, показывающий эти данные.

Что нам нужно знать: Первое строка данных равна 1 (строка 0 является строкой заголовка), а текущая последняя строка данных равна 3. Последняя строка данных увеличится. Столбец категории равен 0 (A), а столбцы серии - 1 (B), 2 (C) и 3 (D). Обратите внимание, что все индексы основаны на 0.

Теперь мы можем запустить следующий код, используя apache poi 4.1.1:

import java.io.FileInputStream;
import java.io.FileOutputStream;

import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.xddf.usermodel.chart.*;

class ExcelChangeChartData {

 static void updateChartData(XSSFChart chart, XSSFSheet dataSheet, 
  int firstDataRow, int lastDataRow, int categoryColumn, int[] seriesColumns) {

  for (XDDFChartData chartData : chart.getChartSeries()) {
   for (int s = 0; s < chartData.getSeriesCount() ; s++) {
    XDDFChartData.Series series = chartData.getSeries(s);
    if (seriesColumns.length > s) {
     XDDFCategoryDataSource category = XDDFDataSourcesFactory.fromStringCellRange(
      dataSheet, new CellRangeAddress(firstDataRow, lastDataRow, categoryColumn, categoryColumn));
     int seriesColumn = seriesColumns[s];
     XDDFNumericalDataSource<Double> values = XDDFDataSourcesFactory.fromNumericCellRange(
      dataSheet, new CellRangeAddress(firstDataRow, lastDataRow, seriesColumn, seriesColumn));
     series.replaceData(category, values);  
     series.plot();
    }
   }
  }
 }

 public static void main(String[] args) throws Exception {

  String[] months = new String[]{"Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
  int firstDataRow = 1;
  int lastDataRow = 3;
  int categoryColumn = 0;
  int[] seriesColumns = new int[]{1,2,3};

  for (int m = 0; m < months.length - 1; m++) {
   String monthSource = months[m];
   String monthResult = months[m+1];
   String filePath = "./ExcelWithChart" + monthSource + ".xlsx";
   java.util.Random random = new java.util.Random();
   XSSFWorkbook workbook = (XSSFWorkbook)WorkbookFactory.create(new FileInputStream(filePath));
   XSSFSheet sheet = workbook.getSheetAt(0);
   XSSFRow row = sheet.createRow(lastDataRow + 1);
   XSSFCell cell = row.createCell(categoryColumn);
   cell.setCellValue(monthResult);
   for (int i = 0; i < seriesColumns.length; i++) {
    cell = row.createCell(seriesColumns[i]);
    cell.setCellValue(random.nextDouble() / 10 + 0.02);
    cell.setCellStyle(sheet.getRow(lastDataRow).getCell(seriesColumns[i]).getCellStyle());
   }
   lastDataRow++;

   XSSFDrawing drawing = sheet.createDrawingPatriarch();
   XSSFChart chart = drawing.getCharts().get(0);
   updateChartData(chart, sheet, firstDataRow, lastDataRow, categoryColumn, seriesColumns);

   filePath = "./ExcelWithChart" + monthResult + ".xlsx";
   FileOutputStream out = new FileOutputStream(filePath);
   workbook.write(out);
   out.close();
   workbook.close();
  }
 }
}

. Это создаст 9 дополнительных Excel файлов ExcelWithChartApr.xlsx ... ExcelWithChartDec.xlsx, где к каждому добавляются данные нового месяца.

Метод updateChartData обновляет данные диаграммы с использованием метода XDDFChartData.Series.replaceData.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...