# Itext Pdf 5 教程

Itext Pdf 5 教程

Itext Pdf 简述

  • Itext PDF 5是一个Java库,用于创建和处理PDF文档。它提供了丰富的功能,可以生成、编辑和操作PDF文件。
  • iText PDF 5允许您创建复杂的PDF文档,包括文本、图像、表格、图形和其他元素。
  • 您可以使用iText PDF 5来生成报表、合并PDF文件、添加水印、加密和解密文档等。
  • 它还支持各种字体和颜色,以及文本和图像的布局和格式设置。
  • iText PDF 5是一个功能强大且灵活的工具,广泛用于Java开发中的PDF处理任务。

Itext Pdf

依赖

  • 使用 Itext Pdf 5需要添加pdf中文支持包等,需要依赖的如下,其中 layoutItext Pdf 7 版本中的
<!-- itextpdf -->
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itextpdf</artifactId>
    <version>5.5.13.3</version>
</dependency>
<!-- pdf 中文支持 -->
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itext-asian</artifactId>
    <version>5.2.0</version>
</dependency>
<!--itext 转化pdf -->
<dependency>
    <groupId>org.xhtmlrenderer</groupId>
    <artifactId>core-renderer</artifactId>
    <version>R8</version>
</dependency>
<!-- 单元格样式等属性 -->
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>layout</artifactId>
    <version>7.2.3</version>
</dependency>

本文说明

效果展示

  • 添加文档
  • 添加表格
  • 添加图像
    在这里插入图片描述

完整测试代码

常用API

创建Document

/**
 * 获取 Document
 *
 * @param byteArrayOutputStream byte array output stream
 * @return Document
 */
private Document getDocument(ByteArrayOutputStream byteArrayOutputStream) {
    PdfDocument pdfDoc = new PdfDocument(new PdfWriter(byteArrayOutputStream, new WriterProperties().setFullCompressionMode(true)));
    // 创建文档对象 设置文档大小为 A4
    Document document = new Document(pdfDoc, PageSize.A4);
    // 设置 document 的 margin
    document.setMargins(10, 10, 10, 10);
    return document;
}

中文字体设置

  • iText-Asian包支持的中文字体如下图
  • iText-Asian包支持的中文字体只有简体的STSong华文宋体和三种繁体
    在这里插入图片描述
引入其它字体
  • 注意不同版本创建字体api不同但是大致一样
// 获取中文字体
PdfFont chineseFont = PdfFontFactory.createFont("src/main/resources/fonts/STSong.ttf", PdfEncodings.IDENTITY_H);
// 获取英文字体
PdfFont englishFont = PdfFontFactory.createFont(FontFactory.TIMES_ROMAN);
  • 注意创建的字体做缓存,如果每次都创建会导致Pdf文件过大

添加段落

/**
 * 获取段落
 *
 * @return Paragraph
 * @throws IOException Io exception
 */
private Paragraph getParagraph() throws IOException {
    // 获取中文字体
    PdfFont chineseFont = PdfFontFactory.createFont("src/main/resources/fonts/STSong.ttf", PdfEncodings.IDENTITY_H);
    // 获取英文字体
    PdfFont englishFont = PdfFontFactory.createFont(FontFactory.TIMES_ROMAN);
    Paragraph englishText = new Paragraph("Hello world!");
    englishText.setFont(englishFont);
    Paragraph chineseText = new Paragraph("你好早安!");
    chineseText.add(englishText);
    chineseText.setFont(chineseFont);
    chineseText.setBorder(getSolidBorder(ItextPdfConst.BLACK));
    return chineseText;
}

字体设置颜色

chineseText.setFontColor(ColorConstants.RED, 2);

Hello World 示例

  • 中文字体使用宋体、英文字体使用新罗马
    在这里插入图片描述
@Test
public void test4() throws IOException {
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    Document document = getDocument(byteArrayOutputStream);
    OutputStream out = new FileOutputStream(FILENAME);
    document.add(getParagraph());
    document.close();
    byteArrayOutputStream.writeTo(out);
}

添加表格

  • 创建10列的表格
/**
 * 获取表格
 *
 * @return IBlockElement
 * @throws IOException io Exception
 */
private IBlockElement getTable() throws IOException {
    Table table = new Table(ItextKernelUtils.TABLE_PROPORTION);
    table.setMargins(5, 5, 5, 5);
    List<Cell> tableCell = getTableCell();
    for (Cell cell : tableCell) {
        table.addCell(cell);
    }
    return table;
}
/**
 * 获取表格中的单元格
 *
 * @return List
 * @throws IOException Io Exception
 */
private List<Cell> getTableCell() throws IOException {
    List<Cell> cellList = new ArrayList<>();
    Cell cell;
    for (int i = 0; i < 20; i++) {
        cell = new Cell();
    cell.add(getCellParagraph(i + 1));
        cellList.add(cell);
    }
    return cellList;
}
  • 文档增加表格
document.add(getTable());

图片打印

/**
 * 获取图片
 *
 * @return Cell
 * @throws MalformedURLException Exception
 */
private Cell getPicture() throws MalformedURLException {
    Cell cell = new Cell();
    Image image = new Image(ImageDataFactory.create("src/main/resources/picture/one.jpg"));
    // 设置等比例缩放
    image.setAutoScale(true);
    cell.add(image);
    return cell;
}
document.add(getPicture());

Pdf添加水印

  • 效果图如下
    在这里插入图片描述
单一水印
/**
 * Pdf 添加水印
 *
 * @param sourceFile 源文件
 * @param targetFile 目标文件
 * @param waterMark  水印
 * @throws IOException       Io exception
 * @throws DocumentException document exception
 */
public static void addWatermark(String sourceFile, String targetFile, String waterMark) throws IOException, DocumentException {
    // 待加水印的文件
    PdfReader reader = new PdfReader(new FileInputStream(sourceFile));
    // 加完水印的文件
    PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(targetFile));
    // 设置字体
    BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
    // 设置透明度
    PdfGState gs = new PdfGState();
    // pdf页数
    int pageCount = reader.getNumberOfPages() + 1;
    PdfContentByte content;
    // 循环对每页插入水印
    for (int i = 1; i < pageCount; i++) {
        // 水印的起始
        content = stamper.getOverContent(i);
        gs.setFillOpacity(0.5f);
        content.setGState(gs);
        // 开始
        content.beginText();
        // 设置颜色 默认为黑色
        content.setColorFill(BaseColor.LIGHT_GRAY);
        // 设置字体及字号
        content.setFontAndSize(baseFont, 50);
        // 开始写入水印
        content.showTextAligned(Element.ALIGN_BASELINE, waterMark, 180, 340, 45);
        content.endText();
    }
    stamper.close();
    reader.close();
}
满屏水印
/**
 * 水印填满整个页面
 *
 * @param stamper       输出已添加水印的文件
 * @param waterMarkName 水印文字
 */
public static void fillUpWaterMark(PdfStamper stamper, String waterMarkName) {
    try {
        BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
        Rectangle pageRect;
        PdfGState gs = new PdfGState();
        // 设置透明度
        gs.setFillOpacity(0.5f);
        gs.setStrokeOpacity(0.5f);
        int total = stamper.getReader().getNumberOfPages();
        JLabel label = new JLabel();
        FontMetrics metrics;
        label.setText(waterMarkName);
        metrics = label.getFontMetrics(label.getFont());
        int textH = metrics.getHeight();
        int textW = metrics.stringWidth(label.getText());
        PdfContentByte under;
        for (int i = 1; i <= total; i++) {
            pageRect = stamper.getReader().getPageSizeWithRotation(i);
            under = stamper.getOverContent(i);
            under.saveState();
            under.setGState(gs);
            under.beginText();
            // 设置水印字体大小颜色
            under.setFontAndSize(base, 20);
            under.setColorFill(BaseColor.RED);
            // 水印文字成30度角倾斜
            float height1 = pageRect.getHeight();
            for (int height = 5 + textH; height < height1; height = height + textH * 3) {
                float width1 = pageRect.getWidth();
                for (int width = 5 + textW; width < width1 + textW; width = width + textW + 3) {
                    under.showTextAligned(Element.ALIGN_LEFT, waterMarkName, width - textW, height - textH, 45);
                }
            }
            // 添加水印文字
            under.endText();
        }
        stamper.close();
    } catch (Exception e) {
        logger.error(e.getMessage(), e);
    }
}

增加一个新区域

/**
  * 增加新的一页
  * @return
  */
private AreaBreak getAreaBreak() {
    AreaBreak areaBreak = new AreaBreak();
    areaBreak.setPageSize(PageSize.A5);
    return areaBreak;
}
// document.add(getAreaBreak());

增加列表

  • 效果如下
    在这里插入图片描述
/**
  * 获取列表
  *
  * @return List
  */
private com.itextpdf.layout.element.List getList() {
    com.itextpdf.layout.element.List list = new com.itextpdf.layout.element.List();
    // Add elements to the list
    list.add("Java");
    list.add("JavaFX");
    list.add("Apache Tika");
    list.add("OpenCV");
    list.add("WebGL");
    list.add("Coffee Script");
    list.add("Java RMI");
    list.add("Apache Pig");
    return list;
}
// document.add(getList());

合并拆分Pdf

  • ItextMergeTest.java
public class ItextMergeTest {


    private static final String FILE_NAME1 = "demo.pdf";
    private static final String FILE_NAME2 = "demo1.pdf";
    private static final String DEST = "MergeDemo.pdf";
    private static final String DEST_FOLDER = "./file/pdftest";

    /**
     * 使用 copyPagesTo 合并
     *
     * @throws IOException ioexception
     */
    @Test
    public void test1() throws IOException {
        PdfWriter pdfWriter = new PdfWriter(DEST);
        // 最终合并的 dpf
        PdfDocument pdfDocument = new PdfDocument(pdfWriter);

        PdfReader pdfReader1 = new PdfReader(FILE_NAME1);
        PdfDocument pdfDocument1 = new PdfDocument(pdfReader1);
        pdfDocument1.copyPagesTo(1, pdfDocument1.getNumberOfPages(), pdfDocument);

        PdfReader pdfReader2 = new PdfReader(FILE_NAME2);
        PdfDocument pdfDocument2 = new PdfDocument(pdfReader2);
        pdfDocument2.copyPagesTo(1, pdfDocument2.getNumberOfPages(), pdfDocument);

        pdfReader1.close();
        pdfDocument1.close();
        pdfReader2.close();
        pdfDocument2.close();
        pdfDocument.close();
    }

    /**
     * 使用  pdfMerger.merge
     *
     * @throws IOException ioexception
     */
    @Test
    public void test2() throws IOException {
        PdfWriter pdfWriter = new PdfWriter(DEST);
        // 最终合并的 dpf
        PdfDocument pdfDocument = new PdfDocument(pdfWriter);
        PdfMerger pdfMerger = new PdfMerger(pdfDocument);

        PdfReader pdfReader1 = new PdfReader(FILE_NAME1);
        PdfDocument pdfDocument1 = new PdfDocument(pdfReader1);
        pdfMerger.merge(pdfDocument1, 1, pdfDocument1.getNumberOfPages());

        PdfReader pdfReader2 = new PdfReader(FILE_NAME2);
        PdfDocument pdfDocument2 = new PdfDocument(pdfReader2);
        pdfMerger.merge(pdfDocument2, 1, pdfDocument2.getNumberOfPages());

        pdfReader1.close();
        pdfDocument1.close();
        pdfReader2.close();
        pdfDocument2.close();
        pdfDocument.close();
    }

    /**
     * 每个文件 1 页 分割
     *
     * @throws IOException ioexception
     */
    @Test
    public void test3() throws IOException {
        pdfSplitter(DEST, 1, DEST_FOLDER);
    }


    /**
     * 在指定目录等分pdf
     *
     * @param fileName 要分割的文档
     * @param pageNum  分割尺寸
     * @param desDir   分割后存储路径
     * @throws IOException ioexception
     */
    private void pdfSplitter(String fileName, Integer pageNum, String desDir) throws IOException {
        PdfReader pdfReader = new PdfReader(fileName);
        PdfDocument pdf = new PdfDocument(pdfReader);
        String name;
        PdfWriter pdfWriter;
        PdfDocument pdfWriterDoc;
        int numberOfPages = pdf.getNumberOfPages();
        for (int i = 1; i <= numberOfPages; i += pageNum) {
            name = desDir + "/" + i + ".pdf";
            File file = new File(name);
            if (!file.exists()) {
                file.createNewFile();
            }
            pdfWriter = new PdfWriter(name);
            pdfWriterDoc = new PdfDocument(pdfWriter);
            int end = Math.min((i + pageNum - 1), pdf.getNumberOfPages());
            //从页数第一页开始,
            pdf.copyPagesTo(i, end, pdfWriterDoc);
            pdfWriterDoc.close();
            pdfWriter.close();
        }
        //关闭
        pdf.close();
        pdfReader.close();

    }

    /**
     * 分割文档,分割后文仔默认存储在原来的文档路径下。
     *
     * @param fileName
     * @param pageNum
     * @throws IOException
     */
    private void pdfSplitter(String fileName, Integer pageNum) throws IOException {
        String desDir = new File(fileName).getParentFile().getAbsolutePath();
        pdfSplitter(fileName, pageNum, desDir);
    }

    /**
     * 返回自定义片段大小的文件,UUID名称命名。
     *
     * @param fileName
     * @param startPage
     * @param endPage
     * @throws IOException
     */
    public void pdfSplitter(String fileName, int startPage, int endPage) throws IOException {
        //源文档
        PdfReader pdfReader = new PdfReader(fileName);
        PdfDocument pdf = new PdfDocument(pdfReader);
        //目标文档名
        String desDir = new File(fileName).getParentFile().getAbsolutePath() + "/" + UUID.randomUUID() + ".pdf";
        //生成目标文档
        PdfWriter pdfWriter = new PdfWriter(desDir);
        PdfDocument outPdfDocument = new PdfDocument(pdfWriter);
        //从页数第一页开始,
        pdf.copyPagesTo(startPage, endPage, outPdfDocument);
        //关闭
        outPdfDocument.close();
        pdfWriter.close();
        pdf.close();
        pdfReader.close();
    }

}

添加页眉

  • 手动控制页眉页脚的位置添加元素,com.itextpdf.text.pdf会使用事件的方式添加
/**
 * 获取页眉
 *
 * @param document document
 * @return Cell
 * @throws IOException ioexception
 */
private Cell getPdfHeader(Document document) throws IOException {
    Cell cell = new Cell();
    // 获取中文字体
    PdfFont chineseFont = PdfFontFactory.createFont("src/main/resources/fonts/STSong.ttf", PdfEncodings.IDENTITY_H);
    Paragraph chineseText = new Paragraph("我是页眉");
    chineseText.setFont(chineseFont);
    cell.setHorizontalAlignment(HorizontalAlignment.CENTER);
    cell.setVerticalAlignment(VerticalAlignment.MIDDLE);
    cell.setTextAlignment(TextAlignment.CENTER);
    cell.add(chineseText);
    cell.setHeight(30);
    float documentAvailableHeight = ItextKernelUtils.getDocumentAvailableHeight(document);
    float value = cell.getHeight().getValue();
    ItextKernelUtils.setDocumentAvailableHeight(document, documentAvailableHeight - value);
    return cell;
}

设置获取文档高度

public class DocumentPropertyConst {
    /**
     * 当前document可用高度
     */
    public static final Integer AVAILABLE_HEIGHT = 8188;
    public static final Integer PRINT_LEVEL = 8189;
    public static final Integer HASHEADER = 8190;
    public static final Integer HASFOOTER = 8191;
    public static final Integer SIKP_HEADER_FOOTER = 8192;
}

/**
 * 设置当前打印页可用高度
 *
 * @param document document
 * @param height   height
 */
public static void setDocumentAvailableHeight(Document document, float height) {
    document.setProperty(DocumentPropertyConst.AVAILABLE_HEIGHT, height);
}

/**
 * 获取文档实际高度
 *
 * @param document document
 * @return float
 */
public static float getDocumentAvailableHeight(Document document) {
    return document.getProperty(DocumentPropertyConst.AVAILABLE_HEIGHT);
}
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

全栈程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值