如何使用iText将图形绘制为PDF?

时间:2011-10-20 03:48:49

标签: java spring-mvc pdf-generation itext graphics2d

我正在尝试完成绘制图形并将其写入PDF的示例,但我不断收到PDF没有页面的错误。如果我在打开后用document.add()添加一些简单的东西就可以正常工作,我只是看不到图形。这是我的代码:

Document document = new Document();
PdfWriter writer = new PdfWriter();
response.setContentType("application/pdf");
response.setHeader("Content-Disposition",
    " attachment; filename=\"Design.pdf\"");

writer = PdfWriter.getInstance(document, response.getOutputStream());

document.open();    
PdfContentByte cb = writer.getDirectContent();
Graphics2D graphics2D = cb.createGraphics(36, 54);
graphics2D.drawString("Hello World", 36, 54);
graphics2D.dispose();   
document.close();

我是否必须做其他事情才能将图形添加到文档中,或者我的语法不正确?

6 个答案:

答案 0 :(得分:6)

我不是IText的专家,但上周我试着用它绘制一些圈子。所以这是我在测试中注意到的:

如果你绘制图形,你必须(或者说我必须尝试它时)将图形命令“包装”在以saveState()开头并以{{1结尾的部分我需要调用restoreState() - 如果我不调用fillStroke()那么就没有画出来。

实施例

fillStroke()

但是private void circle(float x, float y, PdfWriter writer) { PdfContentByte canvas = writer.getDirectContent(); canvas.saveState(); canvas.setColorStroke(GrayColor.BLACK); canvas.setColorFill(GrayColor.BLACK); canvas.circle(x, y, 2); canvas.fillStroke(); canvas.restoreState(); } @Test public void testPossition() throws DocumentException, IOException { OutputStream outputStream = FileUtil.openOutputStream("testPosition.pdf"); //this is my personal file util, but it does not anything more //then creating a file and opening the file stream. Document document = new Document(PageSize.A4, 50, 50, 50, 50); PdfWriter writer = PdfWriter.getInstance(document, outputStream); document.open(); markPosition(100, 100, writer); document.add(new Paragraph("Total: 595 x 842 -- 72pt (1 inch)")); document.close(); outputStream.flush(); outputStream.close(); } private void markPosition(float x, float y, PdfWriter writer) throws DocumentException, IOException { placeChunck("x: " + x + " y: " + y, x, y, writer); circle(x, y, writer); } private void placeChunck(String text, float x, float y, PdfWriter writer) throws DocumentException, IOException { PdfContentByte canvas = writer.getDirectContent(); BaseFont font = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED); canvas.saveState(); canvas.beginText(); canvas.moveText(x, y); canvas.setFontAndSize(font, 9); canvas.showText(text); canvas.endText(); canvas.restoreState(); } (canvas)有更多功能,例如PdfContentByte

答案 1 :(得分:4)

Document doc = new Document(PageSize.A4); 有什么不同吗?

我不知道你是否需要像这样添加Paragraph

doc.add(new Paragraph(...));

我们还使用doc.add(ImgRaw);添加图片。

答案 2 :(得分:3)

不要太过分,我认为你的一般方法很好。我认为这里可能发生的是Graphics2D原点与PDF原点不同,所以你可能需要更改对drawString()的调用,所以它使用0,0作为位置?

答案 3 :(得分:3)

我认为问题在于directcontent直接写入页面对象。这样您就可以添加背景或背景图像。在写入直接内容之前,请尝试添加新页面(doc.newPage())。

答案 4 :(得分:3)

您是否尝试过仅使用形状而非文字的g2d对象进行绘图操作?这样可以消除字体选择或其他类似事情发生奇怪的可能性。

iText In Action第12章正是您所寻找的 - 它确实值得一试。 Preview of Chapter 12

答案 5 :(得分:1)

我刚刚对iText的最新HEAD进行了以下单元测试:

    Document document = new Document();
    PdfWriter writer = new PdfWriter();
    ByteArrayOutputStream baos = new ByteArrayOutputStream();

    writer = PdfWriter.getInstance(document, baos);

    document.open();    
    PdfContentByte cb = writer.getDirectContent();
    Graphics2D graphics2D = cb.createGraphics(36, 54);
    graphics2D.setColor(Color.black);
    graphics2D.drawRect(0, 0, 18, 27);

    Font font = new Font("Serif", Font.PLAIN, 10);
    graphics2D.setFont(font);

    graphics2D.drawString("Yo Adrienne", 0, 54); 


    graphics2D.dispose();   
    document.close();

    TestResourceUtils.openBytesAsPdf(baos.toByteArray());

它工作正常 - 我在页面的左下角有一个小的黑色矩形,加上文字。请注意,我为我的drawString方法指定了X = 0(您指定了36,这导致文本在图像边界之外渲染)。另请注意,我明确指定了一种字体 - 如果我将其删除,它仍会呈现,但通常不相信这种事情的默认值通常是个好主意。最后,我明确地设置了前景色 - 再次,并非真正必要,但信任默认值可能会很吓人。

所以我不得不说这里的核心问题是文本在x = 36处的位置。

在我的测试中,没有一个能够创建一个错误,说明PDF没有页面 - 你能发布你得到的异常的堆栈跟踪吗?

我无法想象在文档中添加一个段落会对此产生任何影响(这就是那种很久以前就会得到解决的错误)