首页 > 代码库 > iText生成PDF的关键源码分析
iText生成PDF的关键源码分析
对于iText的学习,基本上都是来源于官网上的例子。这和我学习easyUI、jQuery的途径都是一致的。
这也再次证明了,想用好一个软件,官方提供的例子和文档都是最佳的学习资料。
因为对方是最了解这款软件的人,设计出来的demo当然是最有应用价值的~
这里吐槽一下,iText的demo真难找,官网上反反复复找了好多次才找到,不知道大家是否和我一样,在这里给大家一个捷径。
下面就拿官网的例子来讲一讲,首先如何生成PDF?
/** * 这也就是所有demo中最核心的代码 * Creates a PDF document. * @param filename the path to the new PDF document * @throws DocumentException * @throws IOException * @throws DocumentException * @throws IOException */ public void createPdf(String filename) throws IOException, DocumentException { // step 1 创建一个文档对象 Document document = new Document(); // step 2 将文档和一个硬盘文件关联,也就是要输出到文件系统了 PdfWriter.getInstance(document, new FileOutputStream(filename)); // step 3 打开文档,只有打开后才能添加内容 document.open(); // step 4 添加内容 BaseFont bf; Font font; for (int i = 0; i < 3; i++) { bf = BaseFont.createFont(MOVIES[i][0], MOVIES[i][1], BaseFont.NOT_EMBEDDED); font = new Font(bf, 12); document.add(new Paragraph(bf.getPostscriptFontName(), font)); for (int j = 2; j < 5; j++) document.add(new Paragraph(MOVIES[i][j], font)); document.add(Chunk.NEWLINE); } // step 5 关闭文档 document.close(); }
其中,Document并不和生成的PDF文档对应,我们看看PdfWriter.getInstance(..)的源码:
public static PdfWriter getInstance(final Document document, final OutputStream os) throws DocumentException { PdfDocument pdf = new PdfDocument(); document.addDocListener(pdf); PdfWriter writer = new PdfWriter(pdf, os); pdf.addWriter(writer); return writer; }
这里又创建了一个PdfDocument,并将它添加到document的DocListener中,很明显,这里是一个观察者模型的应用。
接下来,对Document对象的所有操作都会被DocListener接收到,并做出相应的动作,比如,我们看看下面document.open()这个方法是如何实现的:
public void open() { if (!close) { open = true; } for (DocListener listener : listeners) { listener.setPageSize(pageSize); listener.setMargins(marginLeft, marginRight, marginTop, <span style="white-space:pre"> </span>marginBottom); listener.open(); } }
看到了吗?里面也调用了所有listener的open方法。add和close方法也都是类似。
所以Document对象在这里担当了被监听的对象,实际上的操作都被应用到了观察者的身上,而观察者继承了Document,并增加了Writer用于输出文件。
当PdfWriter被添加到一个指定的PdfDocument上时,那么对Document的任何添加操作都会被写到关联的OutputStream中。
根据上面说的,其实我们可以对一个document添加多个,比如:
// creation of the document with a certain size and certain margins Document document = new Document(PageSize.A4, 50, 50, 50, 50); try { // creation of the different writers HtmlWriter.getInstance(document , System.out); PdfWriter.getInstance(document , new FileOutputStream("text.pdf")); // we add some meta information to the document document.addAuthor("Bruno Lowagie"); document.addSubject("This is the result of a Test."); // we open the document for writing document.open(); document.add(new Paragraph("Hello world")); } catch(DocumentException de) { System.err.println(de.getMessage()); } document.close();
这样的话对document添加的信息,就既能出现在控制台,又能出现在text.pdf中了
iText生成PDF的关键源码分析