JAVA-创建PDF文档

这篇具有很好参考价值的文章主要介绍了JAVA-创建PDF文档。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、前期准备

1、中文字体文件

2、maven依赖

二、创建PDF文档方法

三、通过可填充PDF模板将业务参数进行填充

1、 设置可填充的PDF表单

2、代码开干,代码填充可编辑PDF并另存文件



一、前期准备

1、中文字体文件

本演示使用的是iText 7版本,如果没有中文字体,那生成的PDF文档涉及中文的区域都无法显示。

现有查找到的PDF免费下载网址如下:

  • 阿里巴巴矢量图标库:除了图标库,该网站还提供了一些免费的字体库供下载和使用。
  • 字由:字由是一个专注于中文字体的网站,提供了一些优质的免费字体供下载。
  • 字体中国:字体中国是一个提供中文字体下载的网站,包含了许多中文设计师的作品。
  • 站长之家字体库:站长之家提供了大量的免费字体库,包含了各种中文字体和英文字体。

2、maven依赖

    <dependencies>

        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext7-core</artifactId>
            <version>7.2.5</version>
            <type>pom</type>
        </dependency>

        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>kernel</artifactId>
            <version>7.2.5</version>
        </dependency>

    </dependencies>

二、创建PDF文档方法

import com.itextpdf.io.image.ImageDataFactory;
import com.itextpdf.kernel.events.Event;
import com.itextpdf.kernel.events.IEventHandler;
import com.itextpdf.kernel.events.PdfDocumentEvent;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.layout.Canvas;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Cell;
import com.itextpdf.layout.element.Image;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.properties.HorizontalAlignment;
import com.itextpdf.layout.properties.TextAlignment;
import com.itextpdf.layout.properties.UnitValue;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;

public class CreatePdf {

    //文件根目录
    public static String RootPath = "D:/files-pdf/";
    // 设置字体文件路径
    //注意:如果没有中文字体,那PDF内容涉及中文的区域都不显示
    public static String fontPath = RootPath + "ZiTiQuanWeiJunHei-W1-2.ttf";

    public static void main(String[] args) {

        String pdfName = "testContent.pdf";

        // 创建 PdfWriter 和 PdfDocument
        PdfWriter writer = null;
        try {
            writer = new PdfWriter(pdfName + ".pdf");
        } catch (FileNotFoundException e) {
            System.out.println("创建PdfWriter失败。。。。。");
            e.printStackTrace();
            return;
        }

        PdfDocument pdfDocument = new PdfDocument(writer);

        // 创建 Document
        Document document = new Document(pdfDocument);

        // 设置页面的边距
        documentMargins(document);

        // 设置页眉和页脚
        headerAndFooter(pdfDocument);

        //编写PDF主体的文档内容 , 这一块是主要编写位置
        setContent(document);

        //添加水印
        addWatermark(pdfDocument);

        // 关闭对象
        document.close();   //document文档要在输出前关闭,不然会提示“java.nio.file.NoSuchFileException: editable.pdf”
        pdfDocument.close();

        // 将生成的 PDF 文件移动到指定目录下
        downloadPdf(RootPath, pdfName);
    }

    /**
     * 获取设置的字体
     *
     * @return PdfFont 字体
     */
    private static PdfFont getFont() {
        // 设置中文字体
        PdfFont font = null;
        try {
            font = PdfFontFactory.createFont(fontPath);
        } catch (IOException e) {
            System.out.println("字体获取失败。。。。。。。。。。。");
            e.printStackTrace();
            return null;
        }
        return font;
    }

    /**
     * 设置页面的边距
     *
     * @param document 内容文档
     */
    private static void documentMargins(Document document) {
        // 上、右、下、左
        int margins = 80;
        document.setMargins(margins, margins, margins, margins);
    }

    /**
     * 设置页眉页脚
     *
     * @param pdfDocument PDF文档
     */
    private static void headerAndFooter(PdfDocument pdfDocument) {

        pdfDocument.addEventHandler(PdfDocumentEvent.START_PAGE, new IEventHandler() {

            @Override
            public void handleEvent(Event event) {
                PdfDocumentEvent docEvent = (PdfDocumentEvent) event;
                PdfPage page = docEvent.getPage();
                PdfCanvas canvas = new PdfCanvas(page);

                // 创建页眉
                Rectangle pageSize = page.getPageSize();

                canvas.beginText()
                        .setFontAndSize(getFont(), 10)
                        .moveText(pageSize.getWidth() / 2, pageSize.getTop() - 20)
                        .showText("这是页眉")
                        .endText();

                // 创建页脚
                canvas.beginText()
                        .setFontAndSize(getFont(), 10)
                        .moveText(pageSize.getWidth() / 2, pageSize.getBottom() + 20)
                        .showText("这是页脚")
                        .endText();

                canvas.release();
            }
        });
    }


    /**
     * 添加水印
     *
     * @param pdfDocument PDF文档
     * @throws MalformedURLException
     */
    private static void addWatermark(PdfDocument pdfDocument) {

        // 加载水印图片
        String watermarkImage = RootPath + "zm5.jpg";
        Image image = null;
        try {
            image = new Image(ImageDataFactory.create(watermarkImage));
        } catch (MalformedURLException e) {
            System.out.println("获取水印图片失败 , e : " + e);
            e.printStackTrace();
            return;
        }

        // 获取 PDF 页面的大小,此处是要以页面区域做参考,后续好设置对应的坐标填充水印
        Rectangle rectanglePageSize = pdfDocument.getDefaultPageSize();

        // 遍历每个页面,添加水印
        for (int i = 1; i <= pdfDocument.getNumberOfPages(); i++) {
            //创建PDF画布
            PdfCanvas pdfCanvas = new PdfCanvas(pdfDocument.getPage(i));

            // 创建 Canvas 画布对象,设置位置和大小
            Canvas canvas = new Canvas(pdfCanvas, rectanglePageSize, true);

            // 在水印画布上添加图片,并设置透明度和位置
            // 上、右、下、左
            image.setOpacity(0.8f).setMargins(600, 200, 0, 300);
            canvas.add(image);

            // 关闭水印画布
            canvas.close();
        }
    }

    /**
     * 生成的 PDF 文件移动到指定目录下
     *
     * @param rootPath 存储目录
     * @param pdfName  PDF文件名
     * @return
     */
    private static String downloadPdf(String rootPath, String pdfName) {

        // 假设生成的 PDF 文件路径为 sourcePath
        Path sourcePath = Paths.get(pdfName + ".pdf");
        // 假设目标目录路径为 targetDirectoryPath
        Path targetDirectoryPath = Paths.get(rootPath);
        // 移动文件到目标目录
        Path targetPath = null;
        try {
            targetPath = Files.move(sourcePath, targetDirectoryPath.resolve(sourcePath.getFileName()), StandardCopyOption.REPLACE_EXISTING);
            // 输出成功信息
            System.out.println("文件移动成功,目标路径:" + targetPath);
            return targetPath.toString();
        } catch (IOException e) {
            // 输出失败信息
            System.out.println("文件移动失败,目标路径:" + targetPath);
            e.printStackTrace();
            return null;
        }
    }

    /**
     * PDF主体内容
     *
     * @param document 文档
     */
    private static void setContent(Document document) {

        // 设置中文字体
        PdfFont font = getFont();

        /********************************  段落内容由 Paragraph 区域编写 ******************************************/
        // 创建段落标题
        Paragraph paragraphTitle = new Paragraph().setFont(font);
        // setBold:设置粗体,setItalic:斜体,setUnderline:下划线
        paragraphTitle.add("这是一份PDF测试文档").setBold().setFontSize(12);
        // 设置段落的对齐方式为居中
        paragraphTitle.setTextAlignment(TextAlignment.CENTER);
        document.add(paragraphTitle);

        // 创建一个可编辑的段落
        Paragraph nameOfStaff = new Paragraph().setFont(font).setFontSize(10);
        nameOfStaff.add("Name of Developer / 开发人员:");
        document.add(nameOfStaff);

        Paragraph fullname = new Paragraph().setFont(font).setFontSize(10);
        fullname.add("____________________(Note: 请写全名)");
        document.add(fullname);

        Paragraph paragraph1 = new Paragraph().setFont(font).setFontSize(9);
        paragraph1.add("这是段落内容!这是段落内容!这是段落内容!这是段落内容!这是段落内容!这是段落内容!这是段落内容!这是段落内容!这是段落内容!" +
                "这是段落内容!这是段落内容!这是段落内容!这是段落内容!这是段落内容!这是段落内容!这是段落内容!这是段落内容!这是段落内容!这是段落内容!" +
                "这是段落内容!这是段落内容!这是段落内容!这是段落内容!这是段落内容!这是段落内容!这是段落内容!这是段落内容!这是段落内容!这是段落内容!" +
                "这是段落内容!这是段落内容!这是段落内容!这是段落内容!这是段落内容!这是段落内容!这是段落内容!这是段落内容!这是段落内容!这是段落内容!" +
                "这是段落内容!这是段落内容!这是段落内容!这是段落内容!这是段落内容!这是段落内容!这是段落内容!这是段落内容!这是段落内容!这是段落内容!");
        document.add(paragraph1);

        Paragraph declare = new Paragraph().setFont(font).setFontSize(9);
        declare.add("I hereby declare that:");
        document.add(declare);

        Paragraph section = new Paragraph().setFont(font).setFontSize(9).setBold().setUnderline();
        section.add("多选项声明确认!Multiple option declaration confirmation!");
        document.add(section);

        // 创建一个带有复选框的列表
        Paragraph paragraph2 = new Paragraph().setFont(font).setFontSize(9);
        paragraph2.add("(Please tick in the box as appropriate)").add("\n");
        paragraph2.add("口 声明内容1。。。声明内容1。。。声明内容1。。。声明内容1。。。声明内容1。。。声明内容1。。。").add("\n");
        paragraph2.add("口 声明内容2。。。声明内容2。。。声明内容2。。。声明内容2。。。声明内容2。。。声明内容2。。。").add("\n");
        document.add(paragraph2);


        /********************************  表格由 Table 区域编写 ******************************************/
        // 创建表格并设置列数和默认宽度
        Table table = new Table(4);
//            table.setMaxWidth(1000);  //固定式宽度
//            table.setAutoLayout();    //根据内容自适应宽度
        table.setWidth(UnitValue.createPercentValue(100));  //页面总宽固定
        // 添加表格标题(合并4列)
        Cell titleCell = new Cell(1, 4);
        // 创建文本对象
        titleCell.add(new Paragraph("Table Title"));
        titleCell.setTextAlignment(TextAlignment.CENTER);
        table.addHeaderCell(titleCell);

        // 添加表头
        table.addHeaderCell("Header 1");
        table.addHeaderCell("Header 2");
        table.addHeaderCell("Header 3");
        table.addHeaderCell("Header 4");

        // 添加表格内容
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 4; j++) {
                Cell cell = new Cell()
                        .setFont(font)
                        .add(new Paragraph("行 " + (i + 1) + ", Col " + (j + 1)))
                        .setWidth(UnitValue.createPercentValue(25));
                table.addCell(cell);
            }
        }
        // 设置表格样式
        table.setHorizontalAlignment(HorizontalAlignment.CENTER);

        // 将表格添加到文档中
        document.add(table);

        /********************************  内容区域编写END ******************************************/
    }

}

三、通过可填充PDF模板将业务参数进行填充

1、 设置可填充的PDF表单

至于编辑器自行查找,免费的基本大多会添加水印。

JAVA-创建PDF文档

设置成功后,如下图,可编辑区高亮显示

JAVA-创建PDF文档

 文章来源地址https://www.toymoban.com/news/detail-465440.html

2、代码开干,代码填充可编辑PDF并另存文件

import com.itextpdf.forms.PdfAcroForm;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class FillingPdfTemplate {

    //文件根目录
    public static String RootPath = "D:/files-pdf/";
    // 设置字体文件路径
    //注意:如果没有中文字体,那PDF内容涉及中文的区域都不显示
    public static String fontPath = RootPath + "ZiTiQuanWeiJunHei-W1-2.ttf";


    public static void main(String[] args) {
        Map<String, String> mapParam = new HashMap<>();
        mapParam.put("fullname", "某某某");
        mapParam.put("Check Box1","On");
        mapParam.put("Check Box2", "Off");
        mapParam.put("account1", "account1");
        mapParam.put("broker1", "broker1");
        mapParam.put("number1", "number1");
        mapParam.put("security1", "security1");
        mapParam.put("sharehold1", "sharehold1");
        mapParam.put("clp1", "clp1");
        mapParam.put("shares1", "shares1");
        mapParam.put("sharehold3", "");
        mapParam.put("clp3", "");
        mapParam.put("shares3", "");
        mapParam.put("name1", "某某某");
        mapParam.put("position", "XXX高级");
        mapParam.put("company", "深圳市XXX科技有限公司");
        mapParam.put("date", "2023-05-24");

        String templatePdfPath = RootPath + "Acrobat-demo.pdf";
        String destPdfPath = RootPath + "Acrobat-demo-result.pdf";
        replaceTextFieldPdf(templatePdfPath, destPdfPath, mapParam);
    }

    /**
     * 获取设置的字体
     *
     * @return PdfFont 字体
     */
    private static PdfFont getFont() {
        // 设置中文字体
        PdfFont font = null;
        try {
            font = PdfFontFactory.createFont(fontPath);
        } catch (IOException e) {
            System.out.println("字体获取失败。。。。。。。。。。。");
            e.printStackTrace();
            return null;
        }
        return font;
    }

    /**
     * 替换PDF文本表单域变量
     *
     * @param templatePdfPath 要替换的pdf全路径
     * @param params          替换参数
     * @param destPdfPath     替换后保存的PDF全路径
     * @throws IOException
     */
    public static final void replaceTextFieldPdf(String templatePdfPath, String destPdfPath,
                                                 Map<String, String> params) {

        PdfDocument pdfDoc = null;
        try {
            pdfDoc = new PdfDocument(new PdfReader(templatePdfPath), new PdfWriter(destPdfPath));
        } catch (IOException e) {
            e.printStackTrace();
        }

        //获取表单信息
        PdfAcroForm pdfAcroForm = PdfAcroForm.getAcroForm(pdfDoc, true);

        //遍历填充预设的值
        Set<Map.Entry<String, String>> entries = params.entrySet();
        entries.stream().forEach(entry -> {
            if(pdfAcroForm.getField(entry.getKey()) != null){
                // 设置表单字段的值
                //复选框类型的:1勾选,2圆圈,3叉叉,4菱形,5方块,6星星
                //如果不想复选框被选中,要设置为"Off",选中设置为"On",注意大小写
                pdfAcroForm.getField(entry.getKey()).setCheckType(1).setValue(entry.getValue() , true).setFont(getFont());
            }
        });
        // 添加表单字段
//        PdfTextFormField textField = PdfFormField.createText(pdfDoc, new Rectangle(100, 100, 200, 20), "newField", "");
//        pdfAcroForm.addField(textField);
        //表单扁平化,设置后生成的文档不可再编辑
//        pdfAcroForm.flattenFields();
        pdfDoc.close();
    }


}

到了这里,关于JAVA-创建PDF文档的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • java超简单实现文档在线预览功能,支持word\excel\text\pdf\图片等格式转pdf,aspost 转pdf部署linux中文乱码解决方案

    一、背景         在工作中需要对上传到服务器的各种类型包括但不限于word、pdf、excel等文件进行在线预览,前端比较菜搞不定,只能本人亲自上。         网上的经验比较多也比较乱, 有的只有预览,没有文件格式转换,有的也不说linux存在字体问题, 本文会直白的给

    2024年04月10日
    浏览(127)
  • 搭建openstack前期准备

    使用准备好的centos7.5.1804的版本镜像搭建两台主机,大致配置如下 安装好centos后先关闭防火墙:  配置本地hosts配置: 然后分别把centos7.5的镜像和iaas2.4的镜像挂载上传到/opt/目录下,并配置好yum源:    然后安装ftp 并配置好compute结点的yum: controller和compute安装先电的包:      然后开

    2024年02月14日
    浏览(38)
  • IOS逆向前期环境准备笔记

    ios系统由于效验问题,只能升级不能降级,需要特别注意, 刷系统可以在爱思上搞定; 越狱推荐使用u盘镜像及本地启动盘制作: 注意,要进去bios,关闭安全启动,不然直接失败: Checkra1n镜像:https://share.weiyun.com/kr63NENg 其他工具:https://blog.6ziz.com/jailbreakdownload 参考教程:

    2024年02月11日
    浏览(42)
  • MetaGPT前期准备与快速上手

    大家好,MetaGPT 是基于大型语言模型(LLMs)的多智能体协作框架,GitHub star数量已经达到31.3k+。 接下来我们聊一下快速上手 一、环境搭建 python 环境最好是 3.9 1.python 环境 利用 anaconda 创建 python3.9 的虚拟环境 2. MetaGpt 下载 也可以采取以下方式 二、MetaGPT配置 1.调用 ChatGPT API

    2024年01月22日
    浏览(40)
  • 使用 Git&GitHub 的前期准备

    本节包含 SSh Key 的设置,从 GitHub 上创建一个仓库,并 clone 到本地,然后对其进行更改,提交,同步到仓库。需要已经下载好了 Git ,并且已经创建了一个 GitHub 账户 1.1 创建 SSH Key 运行这条命令,然后直接敲两次回车就可以。第一次回车是将 SSH 密匙存放在默认的路径下,第

    2024年01月20日
    浏览(40)
  • 使用whisper生成音频字幕——前期准备

    最近我们要写一个把没有字幕的音频生成字幕的APP,前期调研的很多方式,使用whisper可以实现,这篇文章就是说一些前期准备工作,我就不自己再写一篇了,参考以下两篇文章就行了。 whisper安装下载和python环境的准备 安装过程中踩过的坑

    2024年02月11日
    浏览(42)
  • 番外3:下载+安装VMware(前期准备)

    step1: 查看自己笔记本电脑配置; step2: 下载并安装VMware (下载地址www.kkx.net/soft/16841.html)这里选择本地普通下载; step3: 安装VMware过程中需要填写密钥(本人用的最后一个) ; #UU54R-FVD91-488PP-7NNGC-ZFAX6 #YC74H-FGF92-081VZ-R5QNG-P6RY4 YC34H-6WWDK-085MQ-JYPNX-NZRA2

    2024年02月07日
    浏览(35)
  • 【UE Sequencer系列】01-前期准备

    新建一个工程 在虚幻商城中将我们需要的三种资产导入到新建的工程中 打开工程可以看到导入的资产 新建两个文件夹,一个用来存放音频,一个用来存放所有的Sequencer 导入音频(只支持wav格式) 选中声波,创建一个sound cue 打开“Forge”关卡 改变视口布局 第一个视口选择“

    2023年04月09日
    浏览(42)
  • Rocky(Centos)安装中文字体(防止中文乱码)

    运行下列命令 若出现,下面截图,则需要安装字体管理软件  安装字体库,运行: 当看到下图的提示信息时说明已安装成功: 1)windows系统中就可以找到,打开c盘下的Windows/Fonts目录: 如上图,我们只需要将我们需要的字体拷贝出来并上传至linux服务器即可(例如:宋体和黑

    2024年02月09日
    浏览(55)
  • 程序员自由创业周记#2:前期准备

    感恩 上次公开了创业的决定后,得到了很多亲朋好友和陌生朋友的鼓励或支持,以不同的形式,感动之情溢于言表。这些都会记在心里,大恩不言谢~ 创业方向 笔者是一名资质平平的iOS开发程序猿,创业项目也就是开发App卖,类型的话主要以工具类为主,优先会解决一些我的

    2024年02月10日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包