如何使用Java生成pdf报告

news2025/5/23 18:20:47

文章目录

      • 一、环境准备与Maven依赖说明
      • 二、核心代码解析
        • 1. 基础文档创建
        • 2. 中文字体处理
        • 3. 复杂表格创建
        • 4. 图片插入
      • 三、完整代码示例
      • 四、最终效果

这篇主要说一下如何使用Java生成pdf,包括标题,文字,图片,表格的插入和调整等相关内容。

一、环境准备与Maven依赖说明

这里我使用的是iTextPDF,依次添加下面的依赖

核心依赖说明:

        <!-- pdf:start -->
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.5.11</version>
        </dependency>
        <dependency>
            <groupId>com.itextpdf.tool</groupId>
            <artifactId>xmlworker</artifactId>
            <version>5.5.11</version>
        </dependency>
        <!-- 支持中文 -->
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext-asian</artifactId>
            <version>5.2.0</version>
        </dependency>
        <!-- 支持css样式渲染 -->
        <dependency>
            <groupId>org.xhtmlrenderer</groupId>
            <artifactId>flying-saucer-pdf-itext5</artifactId>
            <version>9.1.16</version>
        </dependency>
        <!-- 转换html为标准xhtml包 -->
        <dependency>
            <groupId>net.sf.jtidy</groupId>
            <artifactId>jtidy</artifactId>
            <version>r938</version>
        </dependency>


        <dependency>
            <groupId>org.java-websocket</groupId>
            <artifactId>Java-WebSocket</artifactId>
            <version>1.5.3</version>
        </dependency>

        <!-- Jetty WebSocket支持 -->
        <dependency>
            <groupId>org.eclipse.jetty.websocket</groupId>
            <artifactId>javax-websocket-server-impl</artifactId>
            <version>9.4.44.v20210927</version>
        </dependency>

        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-webapp</artifactId>
            <version>9.4.44.v20210927</version>
        </dependency>

        <!-- Apache HttpClient -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.13</version>
        </dependency>


二、核心代码解析

1. 基础文档创建

文档的创建:

// 创建A4文档,设置页边距(左、右、上、下)
Document document = new Document(PageSize.A4, 40, 40, 40, 40);
PdfWriter writer = PdfWriter.getInstance(document, outputStream);

// 必须显式打开文档
document.open();
2. 中文字体处理

字体调整:

// 使用内置STSong-Light字体
BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
Font bodyFont = new Font(bf, 12);

// 推荐做法:使用外部字体文件
BaseFont externalFont = BaseFont.createFont("fonts/SourceHanSansCN-Regular.ttf", 
                                          BaseFont.IDENTITY_H, 
                                          BaseFont.EMBEDDED);
3. 复杂表格创建

表格创建:

// 创建5列表格,设置列宽比例
float[] colWidths = {2f, 1.5f, 1.5f, 1.5f, 1.5f};
PdfPTable table = new PdfPTable(colWidths);

// 设置表格占页面宽度的100%
table.setWidthPercentage(100);

// 添加表头
addTableHeader(table, new String[]{"指标", "Q1", "Q2", "Q3", "Q4"}, headerFont);

// 添加数据行
addTableRow(table, new String[]{"响应时间(ms)", "230", "180", "150", "120"}, bodyFont);
4. 图片插入

插入本地图片:

// 推荐使用相对路径
String imagePath = "src/main/resources/charts/tech_trend.png";

// 自动缩放适应宽度
Image image = Image.getInstance(imagePath);
image.scaleToFit(document.getPageSize().getWidth() - 80, Float.MAX_VALUE);
image.setAlignment(Image.ALIGN_CENTER);

// 添加图片描述
Paragraph caption = new Paragraph("图1 2023年季度性能趋势对比", captionFont);
caption.setAlignment(Element.ALIGN_CENTER);
document.add(caption);
document.add(image);

三、完整代码示例

下面是完整的代码示例,可以直接调整使用


import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.draw.LineSeparator;
import com.ruoyi.RuoYiApplication;
import com.ruoyi.common.utils.http.HttpUtils;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.io.*;
import java.text.ParseException;


@RunWith(SpringRunner.class)
@SpringBootTest(classes= RuoYiApplication.class)
public class pdfDemoTest5 {


    /**
     * PDF生成- 公司年度技术报告
     */
    @Test
    public void generateDemoPdf() throws Exception {
        // 文档设置(调整页边距)
        Document document = new Document(PageSize.A4, 40, 40, 40, 40);
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("tech_report_demo.pdf"));

        // 创建中文字体
        BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);

        // 定义字体样式
        Font redTitleFont = new Font(bf, 20, Font.BOLD, BaseColor.RED);
        Font programFont = new Font(bf, 16, Font.BOLD);
        Font sectionFont = new Font(bf, 14, Font.BOLD);
        Font bodyFont = new Font(bf, 12);
        Font tableHeaderFont = new Font(bf, 12, Font.BOLD);
        Font contactFont = new Font(bf, 11, Font.BOLD);

        document.open();

        // ========== 标题区块 ==========
        Paragraph program = new Paragraph();
        program.add(new Chunk("2023年度技术发展报告\n", programFont));
        program.add(new Chunk("科技创新与数字化转型", programFont));
        program.setAlignment(Element.ALIGN_CENTER);
        program.setSpacingAfter(15f);
        document.add(program);

        // 红色主标题(带下划线)
        Paragraph mainTitle = new Paragraph("技术研发中心年度报告", redTitleFont);
        mainTitle.setAlignment(Element.ALIGN_CENTER);
        mainTitle.setSpacingAfter(10f);
        document.add(mainTitle);

        // ========== 期号信息 ==========
        Paragraph issue = new Paragraph();
        issue.add(new Chunk("[2023]年度报告", bodyFont));
        issue.add(new Chunk("                                   ", bodyFont)); // 空格占位
        issue.add(new Chunk("发布日期:[2024]年[1]月[15]日", bodyFont));
        issue.setAlignment(Element.ALIGN_RIGHT);
        document.add(issue);

        // 添加下划线效果
        Chunk underline = new Chunk(new LineSeparator(1.5f, 100f, BaseColor.RED, Element.ALIGN_CENTER, -1));
        document.add(underline);

        // ========== 报告标题 ==========
        Paragraph reportTitle = new Paragraph(
                "2023年度技术研发成果与2024年展望",
                sectionFont);
        reportTitle.setAlignment(Element.ALIGN_CENTER);
        reportTitle.setSpacingBefore(15f);
        reportTitle.setSpacingAfter(20f);
        document.add(reportTitle);

        // ========== 正文内容 ==========
        // 年度总结部分
        addSection(document, "1. 年度技术成果总结", sectionFont,
                "2023年,我司在人工智能、大数据分析和云计算领域取得了显著进展。主要成果包括完成了新一代智能分析平台的开发,实现了数据处理效率提升300%;发布了基于机器学习的预测模型,准确率达到行业领先水平;完成了核心系统的云原生改造,系统稳定性提升至99.99%。", bodyFont);

        // 技术指标部分
        addSection(document, "2. 关键技术指标", sectionFont, "", bodyFont);

        // 表格样式优化
        float[] colWidths = {2f, 1.5f, 1.5f, 1.5f, 1.5f};

        // 创建表格标题
        Paragraph tableCaption = new Paragraph("表1 2023年关键技术指标对比", bodyFont);
        tableCaption.setAlignment(Element.ALIGN_CENTER);
        tableCaption.setSpacingBefore(10f);
        tableCaption.setSpacingAfter(5f);
        document.add(tableCaption);

        // 创建表格
        createComparisonTable(document,
                new String[]{"系统响应时间(ms)", "230", "180", "150", "120"},
                new String[]{"数据处理量(TB/天)", "5.2", "8.7", "12.4", "15.8"},
                colWidths, tableHeaderFont, bodyFont);

        // ========== 技术趋势图 ==========
        Paragraph imageParagraph = new Paragraph();
        imageParagraph.setSpacingBefore(20f);
        imageParagraph.add(new Chunk("图1 2023年技术发展趋势", bodyFont));
        imageParagraph.setAlignment(Element.ALIGN_CENTER);
        document.add(imageParagraph);

        // 插入本地图片(示例)
        String localImagePath = "D:\\test.jpg";
        Image localImage = Image.getInstance(localImagePath);
        localImage.scaleToFit(400, 250);
        localImage.setAlignment(Image.ALIGN_CENTER);
        document.add(localImage);

        // ========== 未来展望 ==========
        addSection(document, "3. 2024年技术发展规划", sectionFont,
                "2024年,我们将重点布局以下领域:\n\n" +
                        "• 人工智能:深化自然语言处理技术应用\n" +
                        "• 边缘计算:构建分布式计算网络\n" +
                        "• 数据安全:实施零信任安全架构\n" +
                        "• 云原生:全面容器化改造\n\n" +
                        "预计2024年研发投入将增长30%,重点培养高端技术人才50名。", bodyFont);

        // ========== 联系方式 ==========
        Paragraph contacts = new Paragraph();
        contacts.add(new Chunk("技术咨询:", contactFont));
        contacts.add(new Chunk(" 400-123-4567   ", bodyFont));
        contacts.add(new Chunk("电子邮箱:", contactFont));
        contacts.add(new Chunk("tech@company.com\n", bodyFont));
        contacts.add(new Chunk("公司地址:", contactFont));
        contacts.add(new Chunk("北京市海淀区科技园区88号 创新大厦B座", bodyFont));
        contacts.setSpacingBefore(20f);
        document.add(contacts);

        document.close();
    }

    // 辅助方法:添加章节
    private void addSection(Document doc, String title, Font titleFont, String content, Font bodyFont) {
        try {
            Paragraph section = new Paragraph(title, titleFont);
            section.setSpacingBefore(15f);
            doc.add(section);

            if(!content.isEmpty()) {
                Paragraph text = new Paragraph(content, bodyFont);
                text.setSpacingAfter(15f);
                doc.add(text);
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }

    // 辅助方法:创建对比表格
    private void createComparisonTable(Document doc,
                                       String[] row1, String[] row2,
                                       float[] colWidths, Font headerFont, Font bodyFont) {
        try {
            PdfPTable table = new PdfPTable(colWidths);
            table.setWidthPercentage(100);
            table.setSpacingBefore(0f); // 标题与表格的间距由外部控制
            table.setSpacingAfter(15f);

            // 表头
            addTableHeader(table, new String[]{"省份", "河南省", "河北省", "山东省", "江苏省", "安徽省"}, headerFont);

            // 数据行
            addTableRow(table, row1, bodyFont);
            addTableRow(table, row2, bodyFont);

            doc.add(table);
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }

    // 辅助方法:添加表头
    private void addTableHeader(PdfPTable table, String[] headers, Font font) {
        for (String header : headers) {
            PdfPCell cell = new PdfPCell(new Paragraph(header, font));
            cell.setBackgroundColor(new BaseColor(240, 240, 240));
            cell.setPadding(5);
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            table.addCell(cell);
        }
    }

    // 辅助方法:添加表格行
    private void addTableRow(PdfPTable table, String[] data, Font font) {
        for (String item : data) {
            PdfPCell cell = new PdfPCell(new Paragraph(item, font));
            cell.setPadding(5);
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            table.addCell(cell);
        }
    }





}

四、最终效果

这个就是上面代码生成的最终的pdf的效果图

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2384069.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

人脸识别备案开启安全防护模式!紧跟《办法》!

国家互联网信息办公室与公安部于 2025 年 3 月 13 日联合公布了《人脸识别技术应用安全管理办法》&#xff08;以下简称《办法》&#xff09;&#xff0c;并自 2025 年 6 月 1 日起正式施行。其中&#xff0c;人脸识别备案成为了规范技术应用、守护信息安全的关键一环。​ 一、…

新浪《经济新闻》丨珈和科技联合蒲江政府打造“数字茶园+智能工厂+文旅综合体“创新模式

5月14日&#xff0c;新浪网《经济新闻》频道专题报道珈和科技在第十四届四川国际茶业博览会上的精彩亮相&#xff0c;并深度聚焦我司以数字技术赋能川茶产业高质量发展创新技术路径&#xff0c;及在成都市“茶业建圈强链”主题推介会上&#xff0c;珈和科技与蒲江县人民政府就智…

50、js 中var { ipcRenderer } = require(‘electron‘);是什么意思?

在 JavaScript 中&#xff0c;var { ipcRenderer } require(‘electron’); 这行代码的含义是&#xff1a; 1. require(‘electron’) 这是 Node.js 的模块引入语法&#xff0c;用于加载 Electron 的核心模块。electron 是 Electron 框架的主模块&#xff0c;提供了构建桌面…

计算机底层的多级缓存以及缓存带来的数据覆盖问题

没有多级缓存的情况 有多级缓存的情况 缓存带来的操作覆盖问题 锁总线带来的消耗太大了。

SpringBoot-1-入门概念介绍和第一个Spring Boot项目

文章目录 1 开发JAVA EE应用1.1 EJB1.2 Spring框架1.2.1 IoC(Inversion of Control)控制反转1.2.2 DI(Dependency Injection)依赖注入1.2.3 AOP面向切面编程1.3 Spring Boot1.4 Spring Cloud框架1.5 开发工具2 创建Spring Boot项目2.1 在线项目生成向导2.2 使用IDEA导入项目2.3…

基于FPGA的电子万年历系统开发,包含各模块testbench

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 5.完整工程文件 1.课题概述 基于FPGA的电子万年历系统开发,包含各模块testbench。主要包含以下核心模块&#xff1a; 时钟控制模块&#xff1a;提供系统基准时钟和计时功能。 日历计算模块&#xff1a…

MySQL 可观测性最佳实践

MySQL 简介 MySQL 是一个广泛使用的开源关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;以其高性能、可靠性和易用性而闻名&#xff0c;适用于各种规模的应用&#xff0c;从小型网站到大型企业级系统。 监控 MySQL 指标是维护数据库健康、优化性能和确保数据…

01-jenkins学习之旅-window-下载-安装-安装后设置向导

1 jenkins简介 百度百科介绍&#xff1a;Jenkins是一个开源软件项目&#xff0c;是基于Java开发的一种持续集成工具&#xff0c;用于监控持续重复的工作&#xff0c;旨在提供一个开放易用的软件平台&#xff0c;使软件项目可以进行持续集成。 [1] Jenkins官网地址 翻译&…

免费开放试乘体验!苏州金龙自动驾驶巴士即将上线阳澄数谷

近日&#xff0c;苏州自动驾驶巴士线路——阳澄数谷示范线正式上线&#xff0c;即日起向全民免费开放试乘体验&#xff01; 在苏州工业园区地铁3号线倪浜•阳澄数谷站外&#xff0c;一辆辆黑、白配色的小巴正在道路上有条不紊地行驶。与普通公交不同的是&#xff0c;小巴造型奇…

每日Prompt:像素风格插画

提示词 像素风格插画&#xff0c;日式漫画脸&#xff0c;画面主体为一位站在路边的男孩&#xff0c;人物穿着黑色冲锋衣&#xff0c;手里拿着手机&#xff0c;男孩靠坐在机车旁边&#xff0c;脚边依偎着一只带着小摩托车头盔的小小猫&#xff0c;背景是雨中&#xff0c;身旁停…

Windows逆向工程提升之二进制分析工具:HEX查看与对比技术

公开视频 -> 链接点击跳转公开课程博客首页 -> ​​​链接点击跳转博客主页 目录 十六进制查看工具 应用于逆向工程的知识点 ​编辑 二进制对比工具 应用于逆向工程的知识点 十六进制查看工具 十六进制查看器是逆向工程的基础工具&#xff0c;它可以以十六进制格式…

2024游戏安全白皮书:对抗激烈!PC游戏外挂功能数增长超149%,超85%移动外挂为定制挂(附获取方式)

2024 年&#xff0c;中国游戏市场实际销售收入达 3257.83 亿元&#xff0c;同比增长 7.53%&#xff1b;用户规模 6.74 亿人&#xff0c;同比增长 0.94%&#xff0c;再创新高。这份庞大的数据背后&#xff0c;更是对安全防线实力的严峻拷问。 在广东省游戏产业协会的指导下&…

12kV 环保气体绝缘交流金属封闭开关设备现场交流耐压试验规范

范围 本文件规定了12kV环保气体绝缘交流金属封闭开关设备现场交流耐压试验的被试设备及试验接线、试验条件、试验步骤、试验判据及异常处理方法。 本文件适用于12kV环保气体绝缘交流金属封闭开关设备现场交流耐压试验&#xff0c;其他气体绝缘交流金属封闭开关设备可参照执行。…

位图算法——判断唯一字符

这道题有多种解法&#xff0c;可以创建hash数组建立映射关系判断&#xff0c;但不用新的数据结构会加分&#xff0c;因此我们有“加分”办法——用位图。 我们可以创建一个整型变量&#xff08;32位&#xff09;而一共才26个字母&#xff0c;所以我们只要用到0-25位即可&#…

【UE5】环形菜单教程

效果 步骤 1. 下载图片资源&#xff1a;百度网盘 请输入提取码 提取码:fjjx 2. 将图片资源导入工程&#xff0c;如下 3. 新建3个控件蓝图&#xff0c;这里分别命名为“WBP_CircularMenu”、“WBP_Highlight”、“WBP_Icon” 4. 打开“WBP_Icon”&#xff0c;设置“所需” 添加…

Athena 执行引擎:在线服务计算的效率王者

引言 在在线服务领域&#xff0c;计算任务呈现出独特的特性&#xff1a;一方面&#xff0c;数据量通常不会过于庞大&#xff0c;因为在线服务对耗时和响应速度有着严苛要求&#xff1b;另一方面&#xff0c;计算任务具有可控性&#xff0c;其大多并非由用户实时输入动态生成&a…

飞桨paddle ‘ParallelEnv‘ object has no attribute ‘_device_id‘【已解决】

书借上回&#xff0c;自从我反复重装paddle之后&#xff0c;我发现了&#xff0c;只要pip list中有库&#xff0c;但是代码报错&#xff0c;那就是飞桨没把代码更新完全&#xff0c;只能自己去改源代码 我又遇到报错了&#xff1a; 根据报错信息&#xff0c;找到ParallelEnv报…

微信小程序之Promise-Promise初始用

我们来尝试使用Promise。 1、需求&#xff0c;做个抽奖的按钮&#xff0c; 抽奖规则&#xff1a; 30%的几率中奖&#xff0c;中奖会提示恭喜恭喜&#xff0c;奖品为10万 RMB 劳斯莱斯优惠券&#xff0c;没中奖会提示再接再厉。 2、先搭界面&#xff1a; <view class&qu…

准备好,开始构建:由 Elasticsearch 向量数据库驱动的 Red Hat OpenShift AI 应用程序

作者&#xff1a;来自 Elastic Tom Potoma Elasticsearch 向量数据库现在被 “基于 LLM 和 RAG 的 AI 生成” 验证模式支持。本文将指导你如何开始使用。 Elasticsearch 已原生集成业内领先的生成式 AI 工具和服务提供商。欢迎观看我们的网络研讨会&#xff0c;了解如何突破 RA…

RNN神经网络

RNN神经网络 1-核心知识 1-解释RNN神经网络2-RNN和传统的神经网络有什么区别&#xff1f;3-RNN和LSTM有什么区别&#xff1f;4-transformer的归一化有哪几种实现方式 2-知识问答 1-解释RNN神经网络 Why&#xff1a;与我何干&#xff1f; 在我们的生活中&#xff0c;很多事情…