java 我正试图使用Apache POI在Word文档上创建条形图,我无法打开word文档,即使文件是成功的

46qrfjad  于 2023-05-15  发布在  Java
关注(0)|答案(1)|浏览(284)

我已经成功地能够使用下面的代码创建一个word文档,但我无法打开创建的word文档。我是新的Apache POI,Java和Web开发,任何帮助将不胜感激。

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 BarChart {
public static void main(String[] args) throws Exception {
     XWPFDocument doc = new XWPFDocument();

    // Create a paragraph
            XWPFParagraph paragraph = doc.createParagraph();
            XWPFRun run = paragraph.createRun();
            run.setText("Bar Chart Example:");

    // Create a severitychart
            XWPFChart categoryChart = 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 the category axis
         XDDFCategoryAxis categoryAxis = categoryChart.createCategoryAxis(AxisPosition.BOTTOM);
         XDDFValueAxis valueAxis = categoryChart.createValueAxis(AxisPosition.TOP);
 
         XDDFChartData data = categoryChart.createData(ChartTypes.BAR,  categoryAxis, valueAxis);
    
    //categoryChart.setTitleText("Evoke");
    XDDFChartData.Series series = data.addSeries(categoryDataSource, valueDataSource);
    //series.setTitle("Fruit Sales", null);

    // Plot the chart
    categoryChart.plot(data);
    
    // Save the document
    FileOutputStream out = new FileOutputStream("bar_chart_document.docx");
    doc.write(out);
    out.close();
    doc.close();

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

}

hgqdbh6s

hgqdbh6s1#

主要问题是图表的系列标题不是可选的。每个系列都需要一个标题来准备图例。
如果你取消评论:

...
//series.setTitle("Fruit Sales", null);
...

一个系列标题将被设置,你应该能够在Microsoft Word中打开该文件。
但还有一些提示:
设置轴交叉的方式-例如在值轴的零点:valueAxis.setCrosses(AxisCrosses.AUTO_ZERO) .
设置AxisCrossBetween,使值轴与类别之间的类别轴交叉。否则,第一个和最后一个类别正好在交叉点上,并且条形图只有一半可见:valueAxis.setCrossBetween(AxisCrossBetween.BETWEEN)
将条形图方向设置为BarDirection.BARBarDirection.COL
设置系列填充颜色-LibreOffice必需的,因为这将不使用默认颜色。
Word中条形图的最小完整示例:

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 BarChartWordMinimal {
    
 public static void main(String[] args) throws Exception {
  XWPFDocument doc = new XWPFDocument();

  // Create some normal XWPF content 
  XWPFParagraph paragraph = doc.createParagraph();
  XWPFRun run = paragraph.createRun();
  run.setText("Bar Chart Example:");
 
  // Create the chart
  XWPFChart categoryChart = doc.createChart(10 * Units.EMU_PER_CENTIMETER, 5 * Units.EMU_PER_CENTIMETER);

  // Create chart data sources
  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 the category axis
  XDDFCategoryAxis categoryAxis = categoryChart.createCategoryAxis(AxisPosition.BOTTOM);
  
  // Create the value axis  - axis position top is illogical for value axis but will not lead to error
  //XDDFValueAxis valueAxis = categoryChart.createValueAxis(AxisPosition.TOP);
  XDDFValueAxis valueAxis = categoryChart.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);

  XDDFChartData data = categoryChart.createData(ChartTypes.BAR,  categoryAxis, valueAxis);
  // Set bar direction
  //((XDDFBarChartData)data).setBarDirection(BarDirection.BAR);   
  ((XDDFBarChartData)data).setBarDirection(BarDirection.COL);   
  
  // Set chart title - optinal
  categoryChart.setTitleText("Evoke");
  
  // Add series
  XDDFChartData.Series series = data.addSeries(categoryDataSource, valueDataSource);
  
  // Set series title - not optional 
  series.setTitle("Fruit Sales", null);

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

  // Plot the chart
  categoryChart.plot(data);
    
  // Save the document
  FileOutputStream out = new FileOutputStream("bar_chart_document.docx");
  doc.write(out);
  out.close();
  doc.close();

  System.out.println("chart created successfully!");
 }
 
 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);
 }
}

相关问题