将jfreechart导出为pptx作为EMF图像 - 线渲染不正确

时间:2014-02-01 20:07:14

标签: java apache-poi jfreechart freehep

我正在尝试使用JFreechart-FreeHEP矢量图形-apache poi XSLF将时间序列XY线图导出到pptx文档中。我遵循的逻辑如下

  • 使用jfreechart创建图表
  • 使用freehep api
  • 将图表导出为emf图像
  • 使用apache poi XSLF lib将此图像添加到pptx幻灯片。

问题在于在EMF图像中渲染线条的方式。请看下面的图片。渲染的线条并不完全笔直,它们有锯齿形。水平线呈直线呈现,但垂直线不呈现为直线,它们类似于 - > / \ / \ / \ / \ / \ / \ / \ / \ / \。感谢任何关于让线条呈现为直线的建议。

此问题仅适用于EMF格式,我尝试使用PNG,JPG格式,并且线条呈现为直线。我之所以使用EMF,是因为在导出到pptx之后,其他图片格式(JPEG / PNG / TIF / BMP)似乎失去了它们的质量 - 清晰度和亮度。

Screen shot of EMF image

我正在使用的代码如下

    chart = createChart(createDataset());
    ChartPanel panel = new ChartPanel(chart);

    EMFGraphics2D emffile = new EMFGraphics2D(new File(
            "C:\\Users\\out\\chart.emf"),
            new Dimension(1500, 600));
    emffile.setDeviceIndependent(true);

    emffile.setRenderingHint(RenderingHints.KEY_RENDERING,
            RenderingHints.VALUE_RENDER_QUALITY);
    emffile.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
            RenderingHints.VALUE_STROKE_NORMALIZE);
    emffile.startExport();
    chart.draw((Graphics2D) emffile.create(), new Rectangle(1500, 600));
    emffile.endExport();
    emffile.closeStream();
    XMLSlideShow pptx = new XMLSlideShow();
    XSLFSlide slide = pptx.createSlide();

    byte[] pptxpic = IOUtils.toByteArray(new FileInputStream(
            "C:\\Users\\out\\chart.emf"));

    int idx = pptx.addPicture(pptxpic, XSLFPictureData.PICTURE_TYPE_EMF);
    XSLFPictureShape pic = slide.createPicture(idx);
    pic.setAnchor(new java.awt.Rectangle(0, 25, 720, 500));

    pptx.write(new FileOutputStream(
            "C:\\Users\\out\\poitest002.pptx"));

1 个答案:

答案 0 :(得分:1)

通过以较高分辨率保存文件然后在幻灯片中插入时裁剪为较低的文件来解决此问题。在将图表插入幻灯片之前,该图表已保存为png文件。

byte[] pptxpic = null;

ChartUtilities.saveChartAsPNG(pngfile, chart, 1000, 800);

pptxpic = IOUtils.toByteArray(new FileInputStream(pngfile));

int idx = pptxTemplate.addPicture(pptxpic,
                XSLFPictureData.PICTURE_TYPE_PNG);
XSLFPictureShape pic = slidedips.createPicture(idx);

pic.setAnchor(new java.awt.Rectangle(0, 60, 960, 630));