Apache POI - When editing chart data in a Word file, it returns to the data defined in the form

前端 未结 1 1109
情深已故
情深已故 2021-01-16 18:31

I have developed a Word function that includes a Chart. When editing chart data in a Word file, it returns to the data defined in the form.

Here are the steps:

相关标签:
1条回答
  • 2021-01-16 19:28

    Using apache poi 4.0.1 changing XDDFChart data needs parallel updating all changes in underlying chart data workbook and the chart itself. The chart holds the cached data while the workbook holds the source data. But both is possible using the high level apache poiclasses. No access to underlying XML beans needed.

    Example

    Word template which has template chart having 2 series and 3 categories:

    Code:

    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    
    import org.apache.poi.xwpf.usermodel.*;
    import org.apache.poi.xddf.usermodel.chart.*;
    import org.apache.poi.xssf.usermodel.*;
    import org.apache.poi.ss.util.CellReference;
    import org.apache.poi.ss.util.CellRangeAddress;
    
    public class WordChangeChartData {
    
     public static void main(String[] args) throws Exception {
    
      String filePath = "TEMP_Chart_SimpleBar.docx"; // has template chart having 2 series, 3 categories
      String filePathNew = "New_Chart_Simple.docx";
    
      Object[][] data = new Object[][] { // 2 series, 3 categories
       {"", "male", "female"}, // series titles
       {"health", 123d, 234d}, // category 1
       {"amount", 345d, 123d}, // category 2
       {"size", 180d, 160d} // category 3
      };
    
      XWPFDocument document = new XWPFDocument(new FileInputStream(filePath));
    
      XWPFChart chart = document.getCharts().get(0);
      XSSFWorkbook chartDataWorkbook = chart.getWorkbook();
      String sheetName = chartDataWorkbook.getSheetName(0);
      XSSFSheet chartDataSheet = chartDataWorkbook.getSheet(sheetName);
    
      if (chart.getChartSeries().size() == 1) { // only one chart data
       XDDFChartData chartData = chart.getChartSeries().get(0);
       if (chartData.getSeries().size() == 2) { // exact two series
    
        int rMin = 1;
        int rMax = 3;
    
        // set new category data (both series)
        XDDFCategoryDataSource category = null;
        int c = 0;
        for (int r = rMin; r < rMax+1; r++) {
         chartDataSheet.getRow(r).getCell(c).setCellValue((String)data[r][c]); // in sheet
        }
        category = XDDFDataSourcesFactory.fromStringCellRange(chartDataSheet, new CellRangeAddress(rMin,rMax,c,c)); // in chart
    
        // series 1
        XDDFChartData.Series series1 = chartData.getSeries().get(0);
        c = 1;
        // set new title
        String series1Title = (String)data[0][c];
        chartDataSheet.getRow(0).getCell(c).setCellValue(series1Title); // in sheet
        if (chartDataSheet.getTables().size() > 0) {
         if (chartDataSheet.getTables().get(0).getCTTable().getTableColumns().getTableColumnList().size() > c)
          chartDataSheet.getTables().get(0).getCTTable().getTableColumns().getTableColumnList().get(c).setName(series1Title);
        }
        series1.setTitle(series1Title, new CellReference(sheetName, 0, c, true, true)); // in chart
    
        // set new values
        XDDFNumericalDataSource<Double> values = null;
        for (int r = rMin; r < rMax+1; r++) {
         chartDataSheet.getRow(r).getCell(c).setCellValue((Double)data[r][c]); // in sheet
        }
        values = XDDFDataSourcesFactory.fromNumericCellRange(chartDataSheet, new CellRangeAddress(rMin,rMax,c,c)); 
        series1.replaceData(category, values);
        series1.plot(); //in chart
    
        // series 2
        XDDFChartData.Series series2 = chartData.getSeries().get(1);
        c = 2;
        // set new title
        String series2Title = (String)data[0][c];
        chartDataSheet.getRow(0).getCell(c).setCellValue(series2Title); // in sheet
        if (chartDataSheet.getTables().size() > 0) {
         if (chartDataSheet.getTables().get(0).getCTTable().getTableColumns().getTableColumnList().size() > c)
          chartDataSheet.getTables().get(0).getCTTable().getTableColumns().getTableColumnList().get(c).setName(series2Title);
        }
        series2.setTitle(series2Title, new CellReference(sheetName, 0, c, true, true)); // in chart
    
        // set new values
        for (int r = rMin; r < rMax+1; r++) {
         chartDataSheet.getRow(r).getCell(c).setCellValue((Double)data[r][c]); // in sheet
        }
        values = XDDFDataSourcesFactory.fromNumericCellRange(chartDataSheet, new CellRangeAddress(rMin,rMax,c,c)); 
        series2.replaceData(category, values);
        series2.plot(); // in chart
    
       }
      }
    
      FileOutputStream out = new FileOutputStream(filePathNew); 
      document.write(out);
      out.close();
      document.close();
     }
    
    }
    

    Result:

    0 讨论(0)
提交回复
热议问题