Java生成PDF笔记整理

  1. 引入依赖, groupId:com.itextpdf, version:8.0.4, artifactId如下
    kernel,io,layout,forms
    
  2. 创建pdf对象
    try(ByteArrayOutputStream outputStream = new ByteArrayOutputStream()){PdfWriter writer = new PdfWriter(outputStream, new WriterProperties().setFullCompressionMode(true));PdfDocument pdfDoc = new PdfDocument(writer);Document document = new Document(pdfDoc, PageSize.LETTER);document.setMargins(5, 15, 36, 15);// 添加内容 ...Table table = .... ; // 创建Table对象document.add(table);//document.close();return outputStream.toByteArray() ;
    }
    
  3. 在pdf每页顶部固定位置添加页眉
     int numberOfPages = pdfDoc.getNumberOfPages();LocalDate now = LocalDate.now();String dateContent = "Date : " + now.getYear()+ "/"+ now.getMonthValue() +"/"+ now.getDayOfMonth() ;Paragraph dateParagraph = new Paragraph(dateContent).setFontSize(7).setFontColor(ColorConstants.BLACK);for (int i = 1; i <= numberOfPages; i++) {String pageContent = "Page: "+ i +" of " + numberOfPages ;Paragraph pageParagraph = new Paragraph( pageContent).setFontSize(7).setFontColor(ColorConstants.BLACK);Rectangle pageSize = pdfDoc.getPage(i).getPageSize();float x = pageSize.getWidth() * 0.6f -2;float y = pageSize.getTop() - 12;doc.showTextAligned(pageParagraph, x, y, i, TextAlignment.LEFT, VerticalAlignment.BOTTOM, 0);doc.showTextAligned(dateParagraph, x + 70, y, i, TextAlignment.LEFT, VerticalAlignment.BOTTOM, 0);}
    
  4. 合并pdf
    // part1Bytes、part2Bytes 为两个pdf文件的字节数组
    try(ByteArrayInputStream part1InputSteam = new ByteArrayInputStream(part1Bytes);ByteArrayInputStream part2InputStream = new ByteArrayInputStream(part2Bytes)){// Create PdfDocument object of each pdfPdfDocument part1Doc = new PdfDocument(new PdfReader(part1InputSteam));PdfDocument part2Doc = new PdfDocument(new PdfReader(part2InputStream));// merger.merge(part1Doc, 1, part1Doc.getNumberOfPages());merger.merge(part2Doc, 1, part2Doc.getNumberOfPages());// Source documents can be closed implicitly after merging,// by passing true to the setCloseSourceDocuments(boolean) methodpart1Doc.close();part2Doc.close();
    }
    

Table 创建及属性配置

  1. 创建Table对象
    Cell cell = ... ; 
    // columnWidth 会使得表格的列宽度按照比例分配
    float[] columnWidth = {1, 2, 1};
    Table table = new Table(UnitValue.createPercentArray(columnWidth))table.addCell(cell);
    
  2. 表格填充整个宽度
    table.useAllAvailableWidth();
    // table.setWidth(UnitValue.createPercentValue(100)); // 也可以设置宽度 
    
  3. 创建普通文本Cell
    Cell cell = new Cell() ;
    // 填充单元格内容
    Paragraph paragraph = new Paragraph(content).setFontSize(7) ;
    cell.add(paragraph);
    
  4. 设置对其方式
      Cell cell = new Cell() ;cell.setTextAlignment(TextAlignment.CENTER) ;cell.setVerticalAlignment(VerticalAlignment.MIDDLE)cell.setHorizontalAlignment(HorizontalAlignment.CENTER) ;
    
  5. 创建图片Cell
    ClassPathResource resource = new ClassPathResource("banner.jpg");
    byte[] bannerData = resource.getContentAsByteArray();
    ImageData imageData = ImageDataFactory.create(bannerData);
    Image banner = new Image(imageData);
    // 设置图片宽度
    banner.setWidth(80) ;
    Cell cell = new Cell().add(banner);
    
  6. 合并单元格
    table.addCell(new Cell(1, 3).add(new Paragraph("Cell with colspan 3")));
    table.addCell(new Cell(2, 1).add(new Paragraph("Cell with rowspan 2")));
    
  7. 去除表格边框
    // 这个设置不生效 table.setBorder(Border.NO_BORDER);
    Cell cell = new Cell() ;
    // ...
    cell.setBorder(Border.NO_BORDER) ;
    

Div 使用

  1. 创建Div对象
     Paragraph divHeader = new Paragraph("Hello : 1" ).setFontSize(7).setMargins(0,0,0,0).setPaddings(0,0,0,0);Paragraph divText = new Paragraph("World : 2").setFontSize(7).setMargins(0,0,0,0).setPaddings(0,0,0,0);Div div = new Div().add(divHeader).add(divText).setWidth(160).setPaddings(8, 0, 0, 0).setHorizontalAlignment(HorizontalAlignment.LEFT) ;
    

IEventHandler 使用(符合event事件的时候在pdf中插入内容)

  1. 继承IEventHandler 接口, 实现handleEvent 方法
    public abstract class HelloHeaderEventHandler implements IEventHandler {private final Document doc;private final Table header;private final float tableHeight;protected HelloHeaderEventHandler(Document doc, Table header){this.doc = doc ;this.header = header ;this.tableHeight = this.calTableHeight(header) ;}@Overridepublic void handleEvent(Event currentEvent) {PdfDocumentEvent docEvent = (PdfDocumentEvent) currentEvent;PdfDocument pdfDoc = docEvent.getDocument();PdfPage page = docEvent.getPage();PdfCanvas canvas = new PdfCanvas(page.newContentStreamBefore(), page.getResources(), pdfDoc);PageSize pageSize = pdfDoc.getDefaultPageSize();float coordX = pageSize.getX() + doc.getLeftMargin();float coordY = pageSize.getTop() - doc.getTopMargin();float width = pageSize.getWidth() - doc.getRightMargin() - doc.getLeftMargin();float height = getHeaderHeight();Rectangle rect = new Rectangle(coordX, coordY, width, height);this.doHandleEvent(canvas, rect);}private void doHandleEvent(PdfCanvas canvas, Rectangle rect) {new Canvas(canvas, rect).add(header).close();}private float getHeaderHeight() {return tableHeight;}private float calTableHeight(Table table){TableRenderer renderer = (TableRenderer) table.createRendererSubTree();renderer.setParent(new DocumentRenderer(doc));// Simulate the positioning of the renderer to find out how much space the header table will occupy.LayoutResult result = renderer.layout(new LayoutContext(new LayoutArea(0, PageSize.A4)));return result.getOccupiedArea().getBBox().getHeight();}
    }
    
  2. PdfDocument 对象添加事件
    PdfWriter writer = new PdfWriter(outputStream, new WriterProperties().setFullCompressionMode(true));
    PdfDocument pdfDoc = new PdfDocument(writer);
    Document document = new Document(pdfDoc, PageSize.LETTER);
    // 
    Table header = ...; // 创建Table对象
    IEventHandler eventHandler = new HelloHeaderEventHandler(document, header)
    pdfDoc.addEventHandler(PdfDocumentEvent.END_PAGE, eventHandler);
    // 设置页面边距
    float topMargin = 3 + eventHandler.getHeaderHeight();
    document.setMargins(topMargin, 15, 36, 15);
    

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

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

相关文章

离线安装python库

1. 下载安装包 在联网机器上安装 # 选择符合目标架构的版本&#xff0c;主要是libc版本和python版本 pip download --platformmanylinux2010_x86_64 --only-binary:all: --python-version3.7.4 tabulate # 或者 pip download --platformmanylinux_2_5_x86_64 --only-binary:a…

do...while循环

基本语法 while循环&#xff0c;是先判断条件再执行。 do...while循环&#xff0c;是先斩后奏&#xff0c;先至少执行一次循环语句块中的逻辑&#xff0c;再判断是否继续。 do {//do while 循环语句块; } while (bool类型的值);注意&#xff1a;do...while语句&#xff0c;存…

Common Lisp笔记

在计划学习函数式编程的时候&#xff0c;我一开始打算学习的是 F#。因为我朋友就是在 DTU 上的学&#xff0c;F# 就是 DTU&#xff08;丹麦理工&#xff09;开发的。但是由于 F# 和微软的 .NET 绑定&#xff0c;而在 macOS 上&#xff0c;目前版本的 .NET 的是有些问题的&#…

2020编程语言排序:探索编程界的热门与趋势

2020编程语言排序&#xff1a;探索编程界的热门与趋势 在数字时代的浪潮中&#xff0c;编程语言作为构建数字世界的基石&#xff0c;其流行度和影响力不容忽视。2020年&#xff0c;各大编程语言在各自的领域里展现出独特的魅力和实力。本文将从四个方面、五个方面、六个方面和…

线性代数|机器学习-P3乘法和因式分解矩阵

文章目录 1. 矩阵分解2. S Q Λ Q T SQ\Lambda Q^T SQΛQT3. A U Σ V T AU\Sigma V^T AUΣVT4. A LU 分解5. 矩阵的四个子空间 1. 矩阵分解 目前我们有很多重要的矩阵分解&#xff0c;每个分解对应于多个前提条件&#xff0c;分解方法&#xff0c;分解后的形状会中如下&…

【Vue】v-for中的key

文章目录 一、引入问题二、分析问题 一、引入问题 语法&#xff1a; key属性 "唯一值" 作用&#xff1a;给列表项添加的唯一标识。便于Vue进行列表项的正确排序复用。 为什么加key&#xff1a;Vue 的默认行为会尝试原地修改元素&#xff08;就地复用&#xff09;…

马宝国和沈有容-UMLChina建模知识竞赛第5赛季第12轮

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 参考潘加宇在《软件方法》和UMLChina公众号文章中发表的内容作答。在本文下留言回答。 只要最先答对前3题&#xff0c;即可获得本轮优胜。 如果有第4题&#xff0c;第4题为附加题&am…

大模型备案语料来源安全要求

大模型备案的语料来源安全要求&#xff0c;对服务提供者的要求如下。 a&#xff09;语料来源管理方面&#xff1a; 1&#xff09;面向特定语料来源进行采集前&#xff0c;应对该来源语料进行安全评估&#xff0c;语料内容中含违法不良信息超过5%的&#xff0c;不应采集该来源…

R语言ggplot2包绘制网络地图

重要提示&#xff1a;数据和代码获取&#xff1a;请查看主页个人信息&#xff01;&#xff01;&#xff01; 载入R包 rm(listls()) pacman::p_load(tidyverse,assertthat,igraph,purrr,ggraph,ggmap) 网络节点和边数据 nodes <- read.csv(nodes.csv, row.names 1) edges…

【Python技术】AI编程新手快速入门学习LangChain大模型框架

如果我们要搞AI智能体&#xff0c;普通人一般 借助腾讯元器、 coze、KIMI 或者其他大平台搞一搞&#xff0c;比如我配置的coze智能体在微信公众号聊天。 对于程序员来说&#xff0c;一言不合就喜欢搞代码。 前面文章也介绍了不少关于AI知识库问答&#xff0c;AIagent 不少开源…

利用AI技术革新学习笔记整理:迈向高效学习的新时代

利用AI技术革新学习笔记整理&#xff1a;迈向高效学习的新时代 在数字化时代&#xff0c;学习方式正在经历一场革命。人工智能&#xff08;AI&#xff09;技术的融入&#xff0c;让学习笔记的整理变得更加高效、智能。本文将探讨如何利用AI整理学习笔记&#xff0c;以及这一技…

指纹采集技术

目录 1.概述 1.1 捺印油墨采集 1.2 现场指纹提取 1.3 在线指纹采集 2. 指纹采集器的关键技术指标 2.1 采集面积 2.2 分辨率 2.3 图像质量 2.4 耐用性 1.概述 最早的指纹采集技术是油墨法&#xff0c;至少已经有上百年的历史。1990年代出现了活体指纹采集器&#xff0c…

数据库(入门)

文章目录 一、数据库(DB) 二、数据库管理系统&#xff08;DBMS&#xff09; 三、SQL&#xff08;结构化查询语言&#xff09; 四、三者的关系 五、端口号&#xff08;port number&#xff09; 一、数据库(DB) 定义&#xff1a;按照一定格式存储数据的一些文件的组合。 简单来…

常用的变量命名

当命名编码中的变量时&#xff0c;清晰、简洁和具有描述性的命名是非常重要的。以下是一些常用的变量名称示例&#xff1a; 整数型变量&#xff1a; countindexnumtotalsizelength 浮点型变量&#xff1a; priceratetemperatureweightheightamount 字符串型变量&#xff1a; …

大数据测试/ETL开发,如何造测试数据

相信很多的小伙伴&#xff0c;有些是大数据测试岗位&#xff0c;有些是ETL开发&#xff0c;都面临着如何要造数据的情况。 1&#xff0c;造数背景 【大数据测试岗位】&#xff0c;比较出名的就是宁波银行&#xff0c;如果你在宁波银行做大数据开发&#xff0c;对着需求开发完…

数学建模 —— 层次分析法(2)

目录 一、层次分析法&#xff08;AHP&#xff09; 二、构造比较判断矩阵 2.1 两两比较法 三、单准则下的排序及一致检验 3.1 单准则下的排序 3.2 一致性检验 四、层次总排序 4.1 层次总排序的步骤 4.2 总排序一致性检验 一、层次分析法&#xff08;AHP&#xff09; 方…

xdp、dpdk、rdma能在同一网卡上同时使用吗?

文心一言 XDP、DPDK和RDMA是三种不同的技术&#xff0c;它们各自在Linux网络性能优化中扮演了不同的角色。关于它们能否在同一网卡上同时使用&#xff0c;我们需要考虑以下几个方面&#xff1a; XDP&#xff08;eXpress Data Path&#xff09;&#xff1a; XDP是Linux内核提供…

SVM算法-非线性分类背后技术详解

引言 支持向量机&#xff08;SVM&#xff09;是一种强大的监督学习算法&#xff0c;广泛应用于分类和回归任务中。本文将详细介绍SVM算法在非线性分类任务中的应用&#xff0c;并通过代码示例来展示其背后的技术精髓。我们将分三大部分来展开&#xff0c;本部分将重点介绍SVM算…

银行批量支付业务功能测试点详细介绍

银行批量支付业务是一种银行业务处理方式&#xff0c;它允许银行将多个支付交易合并为一个批次&#xff0c;然后一次性进行处理。这种方式通常用于处理大量、重复性高或定期发生的支付交易&#xff0c;如工资发放、定期账单支付等。 主要作用&#xff1a; 提高效率&#xff1…

【C++面试50题】

以下是针对C程序员面试可能遇到的一些问题&#xff0c;涵盖了从基础语法、面向对象、STL、内存管理、模板、异常处理、并发编程等多个方面。 ### 基础概念与语法 1. C与C的主要区别是什么&#xff1f; 2. 什么是构造函数和析构函数&#xff1f;它们何时被调用&#xff1f; 3. 什…