当前位置: 首页 > news >正文

【pdf】Java代码生成PDF

目录

依赖

创建单元格

表格数据行辅助添加方法

创建表头单元格

创建下划线

创建带下划线的文字

创建PDF


依赖

<dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.4.2</version>
</dependency>
<dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>2.0.13</version>
</dependency>
<dependency><groupId>com.itextpdf</groupId><artifactId>itext-asian</artifactId><version>5.2.0</version>
</dependency>

创建单元格

    /*** 创建单元格** @param text            显示值* @param font            字体* @param horizontalAlign 值水平显示位置(例:Element.ALIGN_CENTER => 居中)* @param verticalAlign   值垂直显示位置(例:Element.ALIGN_MIDDLE => 居中)* @param minHeight       最小行高* @return PdfPCell*/private static PdfPCell createCell(String text, Font font, int horizontalAlign, int verticalAlign, float minHeight) {Paragraph para = new Paragraph(text, font);para.setAlignment(horizontalAlign);para.setLeading(para.getLeading() * 1.2f);PdfPCell cell = new PdfPCell(para);cell.setHorizontalAlignment(horizontalAlign);// 水平居中cell.setVerticalAlignment(verticalAlign);// 垂直居中cell.setMinimumHeight(minHeight);  // 设置最小高度
//        cell.setPadding(0);// 内边距cell.setBorderWidth(0.5f);// 单元格边框宽度cell.setNoWrap(false);// 自动换行return cell;}

表格数据行辅助添加方法

    /*** 辅助添加表格数据行* @param table     表格* @param col1      列1值* @param col2      列2值* @param col3      列3值* @param font      字体*/private static void addTableRow(PdfPTable table, String col1, String col2, String col3, Font font) {// 有几列几个 table.addCell 方法table.addCell(createCell(col1, font, Element.ALIGN_CENTER, Element.ALIGN_MIDDLE, 25f));table.addCell(createCell(col2, font, Element.ALIGN_CENTER, Element.ALIGN_MIDDLE, 25f));table.addCell(createCell(col3, font, Element.ALIGN_CENTER, Element.ALIGN_MIDDLE, 25f));}
    /*** 辅助添加表格行数据* @param table                 表格* @param tableHeaderNumber     表格表头列数* @param font                  字体* @param horizontalAlign       值水平显示位置(例:Element.ALIGN_CENTER => 居中)* @param verticalAlign         值垂直显示位置(例:Element.ALIGN_MIDDLE => 居中)* @param minHeight             最小行高* @param column                单元格数据,x列传入x个使用【,】隔开*/private static void addTableRow(PdfPTable table,int tableHeaderNumber, Font font, int horizontalAlign, int verticalAlign, float minHeight, String... column) {if (column.length == 1 && column[0].isEmpty()) {// 只传入一个【""】值if (tableHeaderNumber > 0) {// 表头列数 <= 0 时,不创建空行数据for (int i = 0; i < tableHeaderNumber; i++) {// 根据表头列数生成对应的空行数据,值为【" "】(为""时不会创建空行数据)table.addCell(createCell(" ", font, horizontalAlign, verticalAlign, minHeight));}}}else {for (String s : column) {table.addCell(createCell(s, font, horizontalAlign, verticalAlign, minHeight));}}}

创建表格表头

    /*** 创建表头单元格** @param table           表* @param text            显示值* @param font            字体* @param bgColor         单元格背景色* @param horizontalAlign 值水平显示位置(例:Element.ALIGN_CENTER => 居中)* @param verticalAlign   值垂直显示位置(例:Element.ALIGN_MIDDLE => 居中)* @param height          行高*/private static void createTableHeader(PdfPTable table, String text, Font font, BaseColor bgColor, int horizontalAlign, int verticalAlign, float height) {Paragraph para = new Paragraph(text, font);para.setAlignment(horizontalAlign);PdfPCell cell = new PdfPCell(para);cell.setBackgroundColor(bgColor);cell.setHorizontalAlignment(horizontalAlign);// 水平居中cell.setVerticalAlignment(verticalAlign);// 垂直居中cell.setMinimumHeight(height);  // 设置最小高度cell.setBorderWidth(0.5f);// 单元格边框宽度
//        cell.setFixedHeight(height);  // 固定行高,文字超出高度不会显示
//        cell.setPadding(8);// 内边距
//        cell.setNoWrap(false);// 自动换行table.addCell(cell);}

创建下划线

    /*** 创建下划线** @param width 宽* @param font  字体* @return Chunk*/private static Chunk createUnderlineChunk(float width, Font font) {Chunk underlineChunk = new Chunk(" ");underlineChunk.setHorizontalScaling(width); // 设置宽度underlineChunk.setUnderline(0.5f, -1f);// param-1:线宽 param-2:线位置,基于行底部,负数下调正数上调underlineChunk.setFont(font);// 设置字体return underlineChunk;}
    /*** 使用PdfContentByte自定义绘制下划线** @param writer PdfWriter* @param width  宽度* @return Chunk*/private static Chunk createCustomDrawnLine(PdfWriter writer, float width) {// 创建一个空白Chunk作为占位符Chunk placeholder = new Chunk(" ");// 添加自定义绘制功能placeholder.setGenericTag(" ");writer.setPageEvent(new PdfPageEventHelper() {@Overridepublic void onGenericTag(PdfWriter writer, Document document,Rectangle rect, String text) {// 获取画布PdfContentByte canvas = writer.getDirectContent();canvas.saveState();// 设置下划线样式canvas.setLineWidth(0.5f);canvas.setColorStroke(BaseColor.BLACK);// 计算下划线位置float y = rect.getBottom() - 3; // 在文本下方3点处float x1 = rect.getLeft();float x2 = x1 + width;// 绘制下划线canvas.moveTo(x1, y);canvas.lineTo(x2, y);canvas.stroke();canvas.restoreState();}});return placeholder;}

创建带下划线的文字

    /*** 创建带下划线的文字块* @param text      文字* @param font      字体* @return          Chunk*/private static Chunk createUnderlinedText(String text, Font font){Chunk textChunk = new Chunk(text, font);textChunk.setUnderline(0.5f, -1f);// 设置下划线:线宽0.5,位置在基线下方1点return textChunk;}

创建PDF

创建 Document 对象、pdf写入器

        Document document = new Document(PageSize.A4, 90, 90, 80, 50);// 创建文档对象(A4纸大小,边距:左, 右, 上, 下)PdfWriter writer = PdfWriter.getInstance(document, Files.newOutputStream(Paths.get(dest)));// 创建PDF写入器
//        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(file));PageNumberEventHandler eventHandler = new PageNumberEventHandler();writer.setPageEvent(eventHandler);// 打开文档document.open();

设置字体,避免中文不显示问题

        // 字体,中文字体,避免文字不显示BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);Font titleFont = new Font(baseFont, 18, Font.BOLD);// 标题字体Font subtitleFont = new Font(baseFont, 12);// 副标题字体Font contentFont = new Font(baseFont, 12);// 正文字体Font headerFont = new Font(baseFont, 12);// 表头字体Font footerFont = new Font(baseFont, 12);// 页脚字体

标题、副标题定义 

        // 标题Paragraph title = new Paragraph("Leslie Lee", titleFont);title.setAlignment(Element.ALIGN_CENTER);// 左右居中title.setSpacingAfter(5f); // 设置段后间距document.add(title);// 副标题Paragraph subtitle = new Paragraph("(風華絕代)", subtitleFont);subtitle.setAlignment(Element.ALIGN_CENTER);subtitle.setSpacingAfter(25f);document.add(subtitle);

 正文段落

        // 添加内容段落Paragraph content = new Paragraph();content.setAlignment(Element.ALIGN_JUSTIFIED); // 段落两端对齐content.add(new Chunk("風華絕代、風流倜儻、玉樹臨風", contentFont));content.add(Chunk.NEWLINE);// 换行,两个效果为空一行content.add(Chunk.NEWLINE);

 正文中添加带下划线的文字

        content.add(createUnderlinedText(text,contentFont));// 正文添加带下划线的文字,需这样单独添加

表格——创建表格

        PdfPTable table = new PdfPTable(3);// 创建表格 x列table.setWidthPercentage(100); // 表格宽度占页面百分比table.setSpacingBefore(5f);  // 表格前间距table.setSpacingAfter(10f);   // 表格后间距table.setSplitLate(false); // 防止单元格在分页时被拆分table.setSplitRows(true);  // 允许行拆分
//        table.setHeaderRows(1); // 前 x 行作为表头,跨页时重复

表格——创建表头-上面的方法

        addTableHeader(table, "代表作", headerFont, null, Element.ALIGN_CENTER, Element.ALIGN_MIDDLE, 25f);// 添加表头单元格,几列就几个 addTableHeader 方法addTableHeader(table, "时间", headerFont, null, Element.ALIGN_CENTER, Element.ALIGN_MIDDLE, 25f);// 添加表头单元格,几列就几个 addTableHeader 方法addTableHeader(table, "角色", headerFont, null, Element.ALIGN_CENTER, Element.ALIGN_MIDDLE, 25f);// 添加表头单元格,几列就几个 addTableHeader 方法

 表格——创建单元格-上面的方法

        addTableRow(table, "絕代風華", "1956-09-12", "Cheung Kwok Wing", contentFont);// 添加表格数据,几行就几个 addTableRow 方法

 添加页脚

        // 添加页脚Paragraph footer = new Paragraph("【风华绝代】", footerFont);footer.setAlignment(Element.ALIGN_CENTER);document.add(footer);

 添加图片

        // 添加图片(可选)try {String imagePath = "img.jpg"; // 替换为实际图片路径Image img = Image.getInstance(imagePath);img.scaleToFit(100, 100); // 调整图片大小img.setAbsolutePosition(36, 36); // 左下角位置document.add(img);} catch (Exception e) {System.err.println("图片添加失败: " + e.getMessage());}

 关闭文档

        document.close();// 关闭文档

 页码处理类

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;import java.io.IOException;/**     页码处理* @author Leslie Lee* @version 2003/04/01* @date 1956/09/12*/
public class PageNumberEventHandler extends PdfPageEventHelper {private final Font footerFont;// 页脚字体private PdfTemplate totalPagesTemplate;// 用于存储总页数的模板private final BaseFont baseFont;// 基础字体public PageNumberEventHandler() throws DocumentException, IOException {super();baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);footerFont = new Font(baseFont, 10, Font.NORMAL, BaseColor.DARK_GRAY);}@Overridepublic void onOpenDocument(PdfWriter writer, Document document) {totalPagesTemplate = writer.getDirectContent().createTemplate(30, 17);// 创建用于总页数的模板}@Overridepublic void onEndPage(PdfWriter writer, Document document) {PdfContentByte canvas = writer.getDirectContent();// 获取PDF内容canvas.saveState();// 保存当前状态// 创建页码文本String footerText = writer.getPageNumber() + " /";// 当前页码// 设置页脚位置(居中底部)float x = (document.left() + document.right()) / 2;// 文档中间位置float y = document.bottom() - 20;// 文档底部上移 20 的位置ColumnText.showTextAligned(canvas, Element.ALIGN_CENTER, new Phrase(footerText, footerFont), x, y, 0);// 添加页码文本float pageTextWidth = baseFont.getWidthPoint(footerText, 9);// 计算页码文本宽度// 添加总页数模板(占位符)canvas.addTemplate(totalPagesTemplate, x + pageTextWidth / 2 + 3, y);  // 计算位置 x为左右位置(数大越右、数小越左) y为垂直位置(减数为下调、加数为上调)// 添加"页"字
//            canvas.beginText();
//            canvas.setFontAndSize(baseFont, 9);
//            canvas.setColorFill(BaseColor.DARK_GRAY);
//            canvas.showTextAligned(Element.ALIGN_CENTER, "页", x + pageTextWidth / 2 + 22, y, 0);
//            canvas.endText();// 添加页码左标题
//            String titleText = "";
//            ColumnText.showTextAligned(canvas, Element.ALIGN_LEFT, new Phrase(titleText, footerFont), document.left(), y, 0);// 添加页码右标题
//            String companyText = "";
//            ColumnText.showTextAligned(canvas, Element.ALIGN_RIGHT, new Phrase(companyText, footerFont), document.right(), y, 0);// 添加页脚分隔线
//            canvas.setLineWidth(0.5f);// 分隔线粗细
//            canvas.setColorStroke(BaseColor.LIGHT_GRAY);// 灰色
//            canvas.moveTo(document.left(), y + 10);// 坐标起点  参数1:开始位置(左右) 参数2:高度(上下) 正数上调负数下调
//            canvas.lineTo(document.right(), y + 10);// 坐标终点 参数1:结束位置(左右) 参数2:高度(上下) 正数上调负数下调
//            canvas.stroke();// 恢复状态canvas.restoreState();}/*** 文档关闭时,写入总页数到模板*/@Overridepublic void onCloseDocument(PdfWriter writer, Document document) {totalPagesTemplate.beginText();totalPagesTemplate.setFontAndSize(baseFont, 10);totalPagesTemplate.setColorFill(BaseColor.DARK_GRAY);totalPagesTemplate.showText(String.valueOf(writer.getPageNumber())); // 有几页封面就减几,没有封面不减totalPagesTemplate.endText();}
}

                                                                Leslie Lee 随笔

http://www.lryc.cn/news/572663.html

相关文章:

  • lingma(阿里云Ai)结合idea使用
  • uni-app-配合iOS App项目开发apple watch app
  • Python按钮点击事件快速入门
  • vue3 reactive重新赋值
  • VSCode1.101.1Win多语言语言编辑器便携版安装教程
  • 【Dify精讲】第14章:部署架构与DevOps实践
  • 字符编码(UTF-8,16,32 和GBK和ASCLL码)
  • 三维视频融合平台:如何构建动态感知的数字空间
  • 配置Fiori应用时报错
  • 从语音到字幕,视频剪辑效率翻倍方案
  • vtk和opencv和opengl直接的区别是什么?
  • Web Splats
  • 每天一个前端小知识 Day 7 - 现代前端工程化与构建工具体系
  • 设计模式实战指南:从源码解析到Java后端架构的艺术
  • mysql查询使用`_rowid` 虚拟列
  • Apipost 签约锐捷网络:AI赋能,共推 ICT 领域 API 生态智能化升级
  • (链表:哈希表 + 双向链表)146.LRU 缓存
  • 性能测试-jmeter实战3
  • 二十二章 stable diffusion SDXL1.0模型 介绍
  • 期货反向跟单-终止盘手合作原则(二)
  • 原点安全入选 Gartner®“数据安全平台”中国市场指南代表厂商
  • Mac电脑-SSH客户端-Termius
  • JetBrains IDE v2025.1 升级,AI 智能+语言支持齐飞
  • Kafka协议开发总踩坑?3步拆解二进制协议核心
  • OpenGL和OpenGL ES区别
  • 可编辑64页PPT | 基于DeepSeek的数据治理方案
  • SaaS+AI架构实战,
  • AWS CloudFormation 实战:使用 App Runner 部署 GlowChat 连接器服务
  • 【AI驱动网络】
  • OpenStack Dashboard在指定可用域(Availability Zone)、指定节点启动实例