📜  iText教程(1)

📅  最后修改于: 2023-12-03 15:01:27.541000             🧑  作者: Mango

iText教程

iText是一个在Java中创建PDF文档的开源库。它提供了一系列的API使得用户可以在PDF文档中添加文本、图像、表单域、表格、列表等内容,还可以进行数字签名和密码保护等操作。iText具有高度的可扩展性和可定制性,同时也支持多种语言。

安装和配置

iText开发环境需要安装Java JDK 5或者更高版本。你可以在iText的官方网站(https://itextpdf.com/)下载iText的jar包和示例代码,或者通过Maven和Gradle等工具下载。

Maven

在Maven中使用iText,需要添加下面的依赖关系:

<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itextpdf</artifactId>
    <version>5.5.13</version>
</dependency>
Gradle

在Gradle中使用iText,需要添加下面的依赖关系:

dependencies {
    compile group: 'com.itextpdf', name: 'itextpdf', version: '5.5.13'
}
创建PDF文档

使用iText创建一个PDF文档需要以下步骤:

  1. 创建Document对象
  2. 创建PdfWriter对象
  3. 打开Document对象
  4. 向Document中添加内容
  5. 关闭Document对象

下面是一个简单的例子,使用iText创建一个包含“Hello World”的PDF文件:

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfWriter;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;

public class HelloWorldPDF {
    public static void main(String[] args) {
        Document document = new Document();
        try {
            PdfWriter.getInstance(document, new FileOutputStream("hello_world.pdf"));
            document.open();
            Paragraph paragraph = new Paragraph();
            paragraph.add("Hello World!");
            document.add(paragraph);
            document.close();
        } catch (DocumentException | FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}
添加文本和字体

使用iText可以在文档中添加文本和字体,代码如下:

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Font;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfWriter;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class TextPDF {
    public static void main(String[] args) {
        Document document = new Document();
        try {
            PdfWriter.getInstance(document, new FileOutputStream("text.pdf"));
            document.open();
            Paragraph paragraph1 = new Paragraph("Hello World!");
            document.add(paragraph1);

            Font font = FontFactory.getFont(FontFactory.COURIER, 16, BaseColor.BLACK);
            Paragraph paragraph2 = new Paragraph("This is some text with a font that is not default.", font);
            document.add(paragraph2);

            BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            Font font2 = new Font(baseFont, 16, Font.BOLD);
            Paragraph paragraph3 = new Paragraph("这是中文", font2);
            document.add(paragraph3);

            document.close();
        } catch (DocumentException | FileNotFoundException | IOException e) {
            e.printStackTrace();
        }
    }
}
添加图像

使用iText可以在PDF文档中添加图像,代码如下:

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.PdfWriter;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class ImagePDF {
    public static void main(String[] args) {
        Document document = new Document();
        try {
            PdfWriter.getInstance(document, new FileOutputStream("image.pdf"));
            document.open();
            Image image = Image.getInstance("image.png");
            document.add(image);
            document.close();
        } catch (DocumentException | FileNotFoundException | IOException e) {
            e.printStackTrace();
        }
    }
}
添加表格

使用iText可以在PDF文档中添加表格,代码如下:

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class TablePDF {
    public static void main(String[] args) {
        Document document = new Document();
        try {
            PdfWriter.getInstance(document, new FileOutputStream("table.pdf"));
            document.open();

            PdfPTable table = new PdfPTable(4);
            PdfPCell cell1 = new PdfPCell(new Paragraph("Cell 1"));
            cell1.setBorderWidth(1f);
            cell1.setHorizontalAlignment(Element.ALIGN_CENTER);

            PdfPCell cell2 = new PdfPCell(new Paragraph("Cell 2"));
            cell2.setBorderWidth(1f);
            cell2.setHorizontalAlignment(Element.ALIGN_CENTER);

            PdfPCell cell3 = new PdfPCell(new Paragraph("Cell 3"));
            cell3.setBorderWidth(1f);
            cell3.setHorizontalAlignment(Element.ALIGN_CENTER);

            PdfPCell cell4 = new PdfPCell(new Paragraph("Cell 4"));
            cell4.setBorderWidth(1f);
            cell4.setHorizontalAlignment(Element.ALIGN_CENTER);

            table.addCell(cell1);
            table.addCell(cell2);
            table.addCell(cell3);
            table.addCell(cell4);

            document.add(table);

            document.close();
        } catch (DocumentException | FileNotFoundException | IOException e) {
            e.printStackTrace();
        }
    }
}
添加表单域

使用iText可以在PDF文档中添加表单域,代码如下:

import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Font;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.TextField;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class FormPDF {
    public static void main(String[] args) {
        Document document = new Document();
        try {
            PdfWriter.getInstance(document, new FileOutputStream("form.pdf"));
            document.open();

            Font font = FontFactory.getFont(FontFactory.COURIER, 16, BaseColor.BLACK);
            BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            Font font2 = new Font(baseFont, 16, Font.BOLD);

            TextField nameField = new TextField(document.getPdfWriter(), null, "Name");
            nameField.setFont(font);
            nameField.setOptions(TextField.REQUIRED);

            TextField ageField = new TextField(document.getPdfWriter(), null, "Age");
            ageField.setFont(font2);

            document.add(new Phrase("Please fill the form:\n\n"));
            document.add(new Phrase("Name: "));
            document.add(nameField.getTextField());
            document.add(new Phrase("\n\nAge: "));
            document.add(ageField.getTextField());

            document.close();
        } catch (DocumentException | FileNotFoundException | IOException e) {
            e.printStackTrace();
        }
    }
}
签名和密码保护

使用iText可以对PDF文档进行签名和密码保护,代码如下:

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.Security;
import java.security.cert.Certificate;

public class SecurePDF {
    public static final String KEYSTORE = "keystore.jks";
    public static final char[] PASSWORD = "password".toCharArray();
    public static final String SRC = "hello_world.pdf";
    public static final String DEST = "signed.pdf";
    public static final String DEST2 = "encrypted.pdf";

    public void createSignedPDF() throws IOException, DocumentException, GeneralSecurityException {
        PdfReader reader = new PdfReader(new FileInputStream(SRC));
        FileOutputStream os = new FileOutputStream(DEST);
        PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0', new File("/tmp"), true);

        PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
        appearance.setReason("Test");
        appearance.setLocation("Test Location");
        appearance.setVisibleSignature(new Rectangle(36, 748, 144, 780), 1, "sig");

        Security.addProvider(new BouncyCastleProvider());

        KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
        keystore.load(new FileInputStream(KEYSTORE), PASSWORD);

        String alias = (String) keystore.aliases().nextElement();
        PrivateKey privateKey = (PrivateKey) keystore.getKey(alias, PASSWORD);
        Certificate[] chain = keystore.getCertificateChain(alias);

        PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED);
        dic.setReason(appearance.getReason());
        dic.setLocation(appearance.getLocation());
        dic.setContact(appearance.getContact());
        dic.setDate(new PdfDate(appearance.getSignDate()));
        dic.setName(PdfPKCS7.getSubjectFields((X509Certificate) chain[0]).getField("CN"));

        PdfSignatureAppearance sap = stamper.getSignatureAppearance();
        sap.setCrypto(privateKey, chain, null, PdfSignatureAppearance.WINCER_SIGNED);
        sap.setCertificate(chain[0]);

        HashMap<PdfName, Integer> exc = new HashMap<>();
        exc.put(PdfName.CONTENTS, new Integer(8192 * 2 + 2));
        sap.preClose(exc);

        PdfPKCS7 sgn = new PdfPKCS7(null, chain, "SHA256", false);
        InputStream data = sap.getRangeStream();
        byte[] buf = new byte[8192];
        int n;
        while ((n = data.read(buf)) > 0) {
            sgn.update(buf, 0, n);
        }

        byte[] pk = sgn.getEncodedPKCS7();
        if (exc.containsKey(PdfName.CONTENTS)) {
            byte[] outc = new byte[8192];
            PdfDictionary dic2 = new PdfDictionary();
            dic2.put(PdfName.CONTENTS, new PdfString(outc).setHexWriting(true));
            sap.close(dic2);
            System.arraycopy(pk, 0, outc, 0, pk.length);
        } else {
            sap.close(pk);
        }
    }

    public void createEncryptedPDF() throws IOException, DocumentException, GeneralSecurityException {
        PdfReader reader = new PdfReader(new FileInputStream(SRC));
        PdfEncryptor.encrypt(reader, new FileOutputStream(DEST2), null, null, PdfWriter.ALLOW_PRINTING);
    }

    public static void main(String[] args) throws IOException, DocumentException, GeneralSecurityException {
        Security.setProperty("crypto.policy", "unlimited");
        SecurePDF app = new SecurePDF();
        app.createSignedPDF();
        app.createEncryptedPDF();
    }
}
总结

iText是一个强大的开源库,可以使得PDF文档的创建和操作更加容易。在本教程中,我们介绍了iText的一些基本操作,例如创建PDF文档、添加文本和字体、添加图像、添加表格、添加表单域、签名和密码保护等。iText还有很多更加高级的功能,例如水印、页面布局、页面大小等等。我们鼓励读者阅读iText的文档和代码,深入了解iText的使用和扩展。