使用iText创建PDF [英] Using iText to create PDF

查看:111
本文介绍了使用iText创建PDF的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用iText创建PDF,但遇到很多困难.简而言之,我想做的是:

  • 阅读pdf模板
  • 在模板的内存中复制一个副本
  • 在副本上绘制表格
  • 将pdf副本写入输出流

到目前为止,看起来像这样

// read in template pdf
InputStream templateStream = getServletContext().getResourceAsStream(labelsTemplate);
PdfReader reader = new PdfReader(templateStream);

// create a table in a new document
Document document = new Document();
PdfCopy copy = new PdfCopy(document, os);
document.open();

PdfPTable table = new PdfPTable(2);
PdfPCell cell;
cell = new PdfPCell(new Phrase("row 1; cell 1"));
table.addCell(cell);
cell = new PdfPCell(new Phrase("row 1; cell 2"));
table.addCell(cell);
document.add(table);

有人可以解释使用PdfReader读取模板后如何制作该模板吗?有没有办法将表格写到模板副本上而不是新文档上?

为以后的参考,这是我所做的:

response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "inline;filename=\"scheduler-labels.pdf\"");
ServletOutputStream os = response.getOutputStream();

// read in template pdf
InputStream templateStream = getServletContext().getResourceAsStream(labelsTemplate);
PdfReader reader = new PdfReader(templateStream);

// make new pdf document to draw table and output to memory
Document document = new Document(reader.getPageSize(1));
ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
PdfWriter.getInstance(document, baos);

// write table
document.open();
PdfPTable table = new PdfPTable(2);
table.setWidthPercentage(110);
PdfPCell cell;
cell = new PdfPCell(new Phrase("row 1; cell 1"));
table.addCell(cell);
cell = new PdfPCell(new Phrase("row 1; cell 2"));
table.addCell(cell);
cell = new PdfPCell(new Phrase("row 2; cell 1"));
table.addCell(cell);
cell = new PdfPCell(new Phrase("row 2; cell 2"));
table.addCell(cell);
document.add(table);
document.close();

// read in newly generated table pdf
PdfReader tableReader = new PdfReader(baos.toByteArray());
ByteArrayOutputStream baosCombined = new ByteArrayOutputStream();
PdfStamper stamper = new PdfStamper(tableReader, baosCombined);

// get a page from the template pdf
PdfImportedPage page = stamper.getImportedPage(reader, 1);

// add to background of table pdf
PdfContentByte background;
background = stamper.getUnderContent(1);
background.addTemplate(page, 0, 0);

stamper.close();
tableReader.close();
reader.close();

// write to servlet output
baosCombined.writeTo(os);
os.flush();
os.close();

解决方案

研究我的注释中引用的示例正是[Tuan]所需的,我将其公式化为答案:

来自 Stationery.java /www.manning.com/lowagie2/samplechapter6.pdf"rel =" nofollow>第 iText in动作-第2版实质上说明了如何在给定PDF的前景填充新内容的同时,将给定PDF的内容用作新PDF的背景(类似文具).

中央代码如下:

public class Stationery extends PdfPageEventHelper
{
    [...]

    public void createPdf(String filename) throws Exception
    {
        // step 1
        Document document = new Document(PageSize.A4, 36, 36, 72, 36);
        // step 2
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(filename));
        useStationary(writer);
        // step 3
        document.open();
        // step 4
        [... add content to PDF ...]
        // step 5
        document.close();
    }

    [...]

    public void useStationary(PdfWriter writer) throws IOException
    {
        writer.setPageEvent(this);
        PdfReader reader = new PdfReader(STATIONERY);
        page = writer.getImportedPage(reader, 1);
    }

    public void onEndPage(PdfWriter writer, Document document)
    {
        writer.getDirectContentUnder().addTemplate(page, 0, 0);
    }

    [...]
}

由于隐式close()调用已越来越近地被删除,因此如今在useStationary中实例化的PdfReader reader应该存储在Stationery的某些变量中,并在执行createPdf之后关闭.

I'm trying to create a PDF using iText and I'm having a great deal of difficulty. In short, what I want to do is:

  • Read in a template pdf
  • Make a copy in memory of the template
  • Draw a table on the copy
  • Write the copy pdf to an outputstream

So far, it's looking like this

// read in template pdf
InputStream templateStream = getServletContext().getResourceAsStream(labelsTemplate);
PdfReader reader = new PdfReader(templateStream);

// create a table in a new document
Document document = new Document();
PdfCopy copy = new PdfCopy(document, os);
document.open();

PdfPTable table = new PdfPTable(2);
PdfPCell cell;
cell = new PdfPCell(new Phrase("row 1; cell 1"));
table.addCell(cell);
cell = new PdfPCell(new Phrase("row 1; cell 2"));
table.addCell(cell);
document.add(table);

Can someone explain how I can make a copy of the template once I've used PdfReader to read it? Is there a way to write the table onto the template copy and not a new document?

For future references, here's what I've done:

response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "inline;filename=\"scheduler-labels.pdf\"");
ServletOutputStream os = response.getOutputStream();

// read in template pdf
InputStream templateStream = getServletContext().getResourceAsStream(labelsTemplate);
PdfReader reader = new PdfReader(templateStream);

// make new pdf document to draw table and output to memory
Document document = new Document(reader.getPageSize(1));
ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
PdfWriter.getInstance(document, baos);

// write table
document.open();
PdfPTable table = new PdfPTable(2);
table.setWidthPercentage(110);
PdfPCell cell;
cell = new PdfPCell(new Phrase("row 1; cell 1"));
table.addCell(cell);
cell = new PdfPCell(new Phrase("row 1; cell 2"));
table.addCell(cell);
cell = new PdfPCell(new Phrase("row 2; cell 1"));
table.addCell(cell);
cell = new PdfPCell(new Phrase("row 2; cell 2"));
table.addCell(cell);
document.add(table);
document.close();

// read in newly generated table pdf
PdfReader tableReader = new PdfReader(baos.toByteArray());
ByteArrayOutputStream baosCombined = new ByteArrayOutputStream();
PdfStamper stamper = new PdfStamper(tableReader, baosCombined);

// get a page from the template pdf
PdfImportedPage page = stamper.getImportedPage(reader, 1);

// add to background of table pdf
PdfContentByte background;
background = stamper.getUnderContent(1);
background.addTemplate(page, 0, 0);

stamper.close();
tableReader.close();
reader.close();

// write to servlet output
baosCombined.writeTo(os);
os.flush();
os.close();

解决方案

As studying the sample referenced in my comment was just what [Tuan] needed, I formulate it as an answer:

The sample Stationery.java from chapter 6 of iText in Action — 2nd Edition essentially shows how to use the contents of a given PDF as background (stationery-like) of a new PDF while filling its foreground with new content.

The central code is as follows:

public class Stationery extends PdfPageEventHelper
{
    [...]

    public void createPdf(String filename) throws Exception
    {
        // step 1
        Document document = new Document(PageSize.A4, 36, 36, 72, 36);
        // step 2
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(filename));
        useStationary(writer);
        // step 3
        document.open();
        // step 4
        [... add content to PDF ...]
        // step 5
        document.close();
    }

    [...]

    public void useStationary(PdfWriter writer) throws IOException
    {
        writer.setPageEvent(this);
        PdfReader reader = new PdfReader(STATIONERY);
        page = writer.getImportedPage(reader, 1);
    }

    public void onEndPage(PdfWriter writer, Document document)
    {
        writer.getDirectContentUnder().addTemplate(page, 0, 0);
    }

    [...]
}

As implicit close() calls have been removed more and more recently, the PdfReader reader instantiated in useStationary nowerdays should be stored in some variable of Stationery and closed after createPdf has executed.

这篇关于使用iText创建PDF的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆