Apache POI - установите две диаграммы рядом в документе Word

Есть ли способ установить две диаграммы рядом в текстовом документе с помощью Apache poi? Я создал две диаграммы, которые идут одна за другой в документ Word.

import java.io.FileOutputStream;
import org.apache.poi.util.Units;
import org.apache.poi.xddf.usermodel.chart.*;
import org.apache.poi.xwpf.usermodel.*;


public class daf {
    public static void main(String[] args) throws Exception {
        // Create a new Word document
        XWPFDocument doc = new XWPFDocument();

        

        // Create a severitychart
        XWPFChart severityChart = doc.createChart(10 * Units.EMU_PER_CENTIMETER, 5 * Units.EMU_PER_CENTIMETER);

        // Create chart data source
        String[] categories = new String[]{"Critical", "High", "Medium","Low","Best Practice"};
        Double[] values = new Double[]{(double) 1,(double) 2,(double) 3,(double) 4,(double) 5};
        XDDFDataSource<String> categoryDataSource = XDDFDataSourcesFactory.fromArray(categories);
        XDDFNumericalDataSource<Double> valueDataSource = XDDFDataSourcesFactory.fromArray(values);

        // Create chart data
        XDDFPieChartData data = (XDDFPieChartData) severityChart.createData(ChartTypes.PIE, null, null);
        
        severityChart.setTitleText("# of Vulnerabilites by Severity");
        severityChart.setTitleOverlay(false);
                
        XDDFChartData.Series series = data.addSeries(categoryDataSource, valueDataSource);
      

        // Plot the chart
        severityChart.plot(data);
        severityChart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).addNewDLbls().addNewShowPercent().setVal(false);;
        severityChart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).getDLbls().addNewShowSerName().setVal(false);
        severityChart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).getDLbls().setSeparator(" - ");
        
        
         // Create a categorychart
            XWPFChart categoryChart = doc.createChart(10 * Units.EMU_PER_CENTIMETER, 5 * Units.EMU_PER_CENTIMETER);

            // Create chart data source
            String[] categories1 = new String[]{"Critical", "High", "Medium","Low","Best Practice"};
            Double[] values1 = new Double[]{(double) 1,(double) 2,(double) 3,(double) 4,(double) 5};
            XDDFDataSource<String> categoryDataSource1 = XDDFDataSourcesFactory.fromArray(categories1);
            XDDFNumericalDataSource<Double> valueDataSource1 = XDDFDataSourcesFactory.fromArray(values1);
                    
         // Create the category axis
         XDDFCategoryAxis categoryAxis = categoryChart.createCategoryAxis(AxisPosition.BOTTOM);
         XDDFValueAxis valueAxis = categoryChart.createValueAxis(AxisPosition.LEFT);
         
         XDDFChartData data1 = categoryChart.createData(ChartTypes.BAR,  categoryAxis, valueAxis);
         
           
            XDDFChartData.Series series1 = data1.addSeries(categoryDataSource1, valueDataSource1);
            series1.setTitle(null); //Title should be mandatory.
            // Plot the chart
            categoryChart.plot(data1);
            
        // Save the document
        FileOutputStream out = new FileOutputStream("chart_document.docx");
        doc.write(out);
        out.close();
        doc.close();

        System.out.println("chart created successfully!");
    }
}

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

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
62
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В документе Microsoft Word в формате Office Open XML (*.docx) диаграммы встроены в тело документа. Так же, как изображения или другие фигуры, они либо находятся на закрепленных рисунках, либо встроены в текст. Пока что Apache POI поддерживает только диаграммы, встроенные в текст. Это текстовые прогоны (XWPFRun). Поэтому они размещаются там, где в документе размещается текстовый ряд.

Использование текущей версии Apache POI 5.2.3 есть три XWPFDocument.createChart метода создания XWPFChart. См. XWPFDocument.

Первый, без параметров, создает диаграмму в новом текстовом прогоне в новом абзаце с размером по умолчанию. Второй имеет параметры width и height и создает диаграмму в новом текстовом прогоне в новом абзаце с заданным размером. Третий имеет параметры run, width и height и создает диаграмму в заданном текстовом прогоне с заданным размером. Таким образом, используя третий, вы имеете полный контроль над тем, где диаграмма должна быть размещена в тексте.

В следующем полном примере создаются две диаграммы в одном абзаце в разных текстовых прогонах в этом абзаце. Таким образом, до тех пор, пока не произойдет автоматический разрыв строки, графики будут располагаться рядом.

import java.io.FileOutputStream;
import org.apache.poi.util.Units;
import org.apache.poi.xddf.usermodel.*;
import org.apache.poi.xddf.usermodel.chart.*;
import org.apache.poi.xwpf.usermodel.*;

public class CreateWordCharts {
    
 private static void createBarChart(XWPFRun run, String[] categories, Double[] values, PresetColor color, 
  BarDirection direction, String chartTitleText, String seriesTitle, 
  int width, int height) throws Exception {
      
  // Create the chart
  XWPFDocument  document = run.getParent().getDocument();
  XWPFChart chart = document.createChart(run, width * Units.EMU_PER_CENTIMETER, height * Units.EMU_PER_CENTIMETER);
  
  // Create chart data sources
  XDDFDataSource<String> categoryDataSource = XDDFDataSourcesFactory.fromArray(categories);
  XDDFNumericalDataSource<Double> valueDataSource = XDDFDataSourcesFactory.fromArray(values);
         
  // Create the category axis
  XDDFCategoryAxis categoryAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
  
  // Create the value axis
  XDDFValueAxis valueAxis = chart.createValueAxis(AxisPosition.LEFT);
  
  // Set how the axis cross - for example at zero point of value axis
  valueAxis.setCrosses(AxisCrosses.AUTO_ZERO);
  
  // Set AxisCrossBetween, so the value axis crosses the category axis between the categories.
  // Else first and last category is exactly on cross points and the bars are only half visible.
  valueAxis.setCrossBetween(AxisCrossBetween.BETWEEN);

  // Create chart data
  XDDFChartData data = chart.createData(ChartTypes.BAR, categoryAxis, valueAxis);
  
  // Set bar direction
  ((XDDFBarChartData)data).setBarDirection(direction);   
  
  // Set chart title - optinal
  if (chartTitleText != null && !chartTitleText.isBlank())
   chart.setTitleText(chartTitleText);
  
  // Add series
  XDDFChartData.Series series = data.addSeries(categoryDataSource, valueDataSource);
  
  // Set series title - not optional 
  if (seriesTitle == null || seriesTitle.isBlank()) seriesTitle = "Series1";
  series.setTitle(seriesTitle, null);

  // Set series fill color - necessary for LibreOffice as this will not use default colors
  solidFillSeries(series, color);

  // Plot the chart
  chart.plot(data);
     
 }

 private static void createPieChart(XWPFRun run, String[] categories, Double[] values, byte[][] colors, 
  String chartTitleText, String seriesTitle, 
  int width, int height) throws Exception {
      
  // Create the chart
  XWPFDocument  document = run.getParent().getDocument();
  XWPFChart chart = document.createChart(run, width * Units.EMU_PER_CENTIMETER, height * Units.EMU_PER_CENTIMETER);
  
  // Create chart data sources
  XDDFDataSource<String> categoryDataSource = XDDFDataSourcesFactory.fromArray(categories);
  XDDFNumericalDataSource<Double> valueDataSource = XDDFDataSourcesFactory.fromArray(values);
         
  // Create chart data
  XDDFChartData data = chart.createData(ChartTypes.PIE, null, null);
  
  // Set chart title - optinal
  if (chartTitleText != null && !chartTitleText.isBlank())
   chart.setTitleText(chartTitleText);
  
  // Add series
  XDDFChartData.Series series = data.addSeries(categoryDataSource, valueDataSource);
  
  // Set series title - not optional 
  if (seriesTitle == null || seriesTitle.isBlank()) seriesTitle = "Series1";
  series.setTitle(seriesTitle, null);
  
  // data point colors; is necessary for showing data points in LibreOffice
  int pointCount = series.getCategoryData().getPointCount();
  for (int p = 0; p < pointCount; p++) {
   chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).addNewDPt().addNewIdx().setVal(p);
   chart.getCTChart().getPlotArea().getPieChartArray(0).getSerArray(0).getDPtArray(p)
    .addNewSpPr().addNewSolidFill().addNewSrgbClr().setVal(colors[p]);
  }

  // Plot the chart
  chart.plot(data);
     
 }

 private static void solidFillSeries(XDDFChartData.Series series, PresetColor color) {
  XDDFSolidFillProperties fill = new XDDFSolidFillProperties(XDDFColor.from(color));
  XDDFShapeProperties properties = series.getShapeProperties();
  if (properties == null) {
   properties = new XDDFShapeProperties();
  }
  properties.setFillProperties(fill);
  series.setShapeProperties(properties);
 }
    
 public static void main(String[] args) throws Exception {
  XWPFDocument document = new XWPFDocument();

  // Create some normal XWPF content 
  XWPFParagraph paragraph = document.createParagraph();
  XWPFRun run = paragraph.createRun();
  run.setText("Chart Examples");

  // Create paragraph for the charts
  paragraph = document.createParagraph();
  // Create run for text
  run = paragraph.createRun();
  run.setText("Chart1: ");

  // Create a run to place the first chart
  run = paragraph.createRun();
  String[] categories = new String[]{"Cat1", "Cat2", "Cat3", "Cat4", "Cat5"};
  Double[] values = new Double[]{3d, 5d, 2d, 4d, 1d};
  createBarChart(run, categories, values, PresetColor.BLUE, BarDirection.COL, "Bar Chart", "Series1", 5, 5);
  
  // Create run for text
  run = paragraph.createRun();
  run.setText(" Chart2: ");
  
  // Create a run to place the second chart
  run = paragraph.createRun();
  categories = new String[]{"Cat1", "Cat2", "Cat3", "Cat4"};
  values = new Double[]{1d, 4d, 3d, 2d};
  byte[][] colors = new byte[][]{
   new byte[]{(byte)255,0,0}, 
   new byte[]{0, (byte)255,0}, 
   new byte[]{0,0,(byte)255}, 
   new byte[]{(byte)255, (byte)255, 0}, 
  };
  createPieChart(run, categories, values, colors, "Pie Chart", null, 5, 5);

  // Create paragraph below the charts
  paragraph = document.createParagraph();
    
  // Save the document
  FileOutputStream out = new FileOutputStream("./WorddocumentWithCharts.docx");
  document.write(out);
  out.close();
  document.close();
 }
 
}

Результат:

Привет, Аксель Рихтер. Спасибо за комментарий. Я создал круговую диаграмму и гистограмму с помощью apache poi, и эти диаграммы шли одна за другой. Отредактировал вопрос и добавил код. Не могли бы вы подсказать мне, как установить круговую диаграмму и гистограмму рядом? Еще раз спасибо за комментарий.

Bharath Naidu Yenumula 22.05.2023 10:08

@Bharath Naidu Yenumula: Ответ остается прежним. Я обновил свой пример. Теперь он создает гистограмму и круговую диаграмму.

Axel Richter 22.05.2023 10:49

То, как вы предоставили детали, а не только решение, похвально. Именно то, что я искал. Решил мои сомнения и спасибо.

Bharath Naidu Yenumula 23.05.2023 11:34

Привет, @Axel Richter, просто из любопытства, есть ли способ сделать форму области диаграммы прямоугольной, а не вышеописанной. Большое спасибо.

Bharath Naidu Yenumula 25.05.2023 17:11

Решил это из вашего ответа на stackoverflow.com/questions/44255527/…. Спасибо за подробную информацию. Это было очень полезно.

Bharath Naidu Yenumula 25.05.2023 17:39

Другие вопросы по теме