java导入pdf(携带动态表格,图片,纯java不需要模板)
java导出pdf文件
- 一、介绍
- 二、准备
- 三、实现效果
- 四、代码
一、介绍
上一篇文章(java使用freemarker操作word(携带动态表格,图片))https://blog.csdn.net/weixin_45853881/article/details/129298494
紧跟上文,现在不仅需要word,而且还要pdf
二、准备
导入依赖,这里使用iText 5没有使用iText 7的,追求快点写,至于iText 7,下次一定
<!-- iText 5核心库-->
<dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.2.0</version>
</dependency>
<!--字体-->
<dependency><groupId>com.itextpdf</groupId><artifactId>itext-asian</artifactId><version>5.2.0</version>
</dependency>
三、实现效果
这里是为了方便查看,就把页码设置在上方了(首页无页码,后续显示页码),下面代码设置的页码就在最下方,所有图片均来源于网络
刚加入了水印设置,懒得截图了也,代码里面有
四、代码
这里把代码都贴上来了,就把一下操作隐藏了,替换为了手敲,先上代码,后展示样式
package com.wy;import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import com.wy.tools.Staff;import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;public class demo {public static void main(String[] args) throws Exception {//临时文件目录String name = "检查报告-" + UUID.randomUUID();FileOutputStream fos = new FileOutputStream("C:\\Users\\admin\\Downloads\\" + name + ".pdf");// 服务器对客户端的HTTP请求的响应对象// HttpServletResponse response// ServletOutputStream os = response.getOutputStream();//新建文档Document document = new Document();// 将内存中的 PDF 文档内容转换为二进制数据,处理流PdfWriter writer = PdfWriter.getInstance(document, fos);writer.setViewerPreferences(PdfWriter.PageModeUseThumbs);writer.setPageSize(PageSize.A4);// 注册页码事件writer.setPageEvent(new PageNumberEvent());// 注册水印事件writer.setPageEvent(new WatermarkEvent());document.open();// 首页part1(document,writer);//内容第一页document.newPage();part3(document);// 查看页码设置生效了没document.newPage();Paragraph con = new Paragraph(" ");document.add(con);// 关闭文档document.close();}// 首页 封面public static void part1(Document document, PdfWriter writer) throws Exception{// pdf首页据上方默认无限边界,所有先设置一个空的 好调整位置,不设置空的也可以,使用时间那里的绝对定位进行设置// 获取页面尺寸信息(A4默认宽595f,高842f,可根据实际调整)float pageWidth = document.getPageSize().getWidth();float pageHeight = document.getPageSize().getHeight();// 计算居中的坐标(x为页面水平中心)float centerX = pageWidth / 2;// 空白占据Paragraph blank = new Paragraph(" "); //有空格,证明有内容,才可以进行设置间距blank.setSpacingBefore(10f); // 上方留出10磅的间距blank.setSpacingAfter(10f); // 下方留出10磅的间距document.add(blank);//logoParagraph title = new Paragraph();Image image = Image.getInstance("https://img-home.csdnimg.cn/images/20201124032511.png");image.scaleToFit(100, 100); // 调整图片大小title.add(new Chunk(image, 18, 0, true));Chunk textChunk = new Chunk("CSND", getFont(14, Font.BOLD));textChunk.setCharacterSpacing(-2f); //字符间距title.add(textChunk);title.setIndentationLeft(25f); //左方缩进document.add(title);//公司Paragraph companyName = new Paragraph();companyName.add(new Chunk("XXX用户", getFont(32,Font.BOLD)));companyName.add(Chunk.NEWLINE);companyName.add(new Chunk("文章检测报告", getFont(32,Font.BOLD)));companyName.setLeading(0, 2.8f);companyName.setAlignment(Element.ALIGN_CENTER);companyName.setSpacingBefore(50f); // 上方留出15磅的间距document.add(companyName);// 时间float bottomY = 130f;ColumnText ct = new ColumnText(writer.getDirectContent());Paragraph time = new Paragraph();time.add(new Chunk("官方检测", getFont(18,Font.BOLD)));time.add(Chunk.NEWLINE);time.add(new Chunk("二〇二五年七月二十九日", getFont(18,Font.BOLD)));time.setLeading(0, 1.8f);time.setAlignment(Element.ALIGN_CENTER);ct.setSimpleColumn(centerX - 200f, //左侧bottomY, //下方centerX + 200f, //右边bottomY + 100f //上边);ct.addElement(time);ct.go();}//内容页public static void part3(Document document) throws Exception{Paragraph title = new Paragraph();title.add(new Chunk("情况汇总表", getFont(18,Font.BOLD)));title.setAlignment(Element.ALIGN_CENTER);title.setSpacingAfter(20f);document.add(title);// 创建一个5列的表格PdfPTable table = new PdfPTable(5);table.setWidthPercentage(100); // 可以减少宽度以避免边缘挤压,根据实际需要设置table.setHorizontalAlignment(Element.ALIGN_CENTER); //表格水平居中// 设置表格列宽比例float[] columnWidths = {1f, 4f, 3f,4f,3f};table.setWidths(columnWidths);// 添加表头String[] headers = {"序号", "姓名", "年龄","职位","图片"};for (String header : headers) {PdfPCell cell = new PdfPCell(new Phrase(header, getFont(12,null)));cell.setHorizontalAlignment(Element.ALIGN_CENTER); //表头水平居中cell.setPadding(5);table.addCell(cell);}// 后续替换为接口对接查询List<Staff> list = new ArrayList<>();list.add(new Staff("1","张三","30","软件工程师","https://n.sinaimg.cn/sinakd20106/384/w2048h1536/20250517/64b2-bd7d404c74b6c162844f652af698d98e.jpg"));list.add(new Staff("2","李四","28","产品经理","https://img1.baidu.com/it/u=1520272912,1660814288&fm=253&fmt=auto&app=138&f=JPEG"));list.add(new Staff("3","王五","26","UI设计师","https://www.vipyl.com/user/webimg/2018123/20181231718374.jpg"));for (Staff staff : list) {addDataCell(table, staff.getId(), getFont(12,null));addDataCell(table, staff.getName(), getFont(12,null));addDataCell(table, staff.getAge(), getFont(12,null));addDataCell(table, staff.getWork(), getFont(12,null));Image image = Image.getInstance(staff.getPic());image.scaleToFit(100, 100);PdfPCell imageCell = new PdfPCell(image, true);imageCell.setHorizontalAlignment(Element.ALIGN_CENTER); // 图片水平居中imageCell.setVerticalAlignment(Element.ALIGN_MIDDLE); // 图片垂直居中imageCell.setPadding(5);table.addCell(imageCell);}// 将表格添加到文档document.add(table);}// 添加数据单元格的辅助方法private static void addDataCell(PdfPTable table, String data, Font font) {PdfPCell cell = new PdfPCell(new Phrase(data, font));cell.setHorizontalAlignment(Element.ALIGN_CENTER); // 水平居中cell.setVerticalAlignment(Element.ALIGN_MIDDLE); // 垂直居中cell.setPadding(5);table.addCell(cell);}// 字体设置public static Font getFont(Integer size,Integer type) throws Exception {if (size == null) size = 12;if (type == null) type = Font.NORMAL;BaseFont bf = BaseFont.createFont("STSong-Light", // 字体名称(宋体)"UniGB-UCS2-H", // 字符编码(简体中文)BaseFont.NOT_EMBEDDED // 不嵌入字体(依赖系统字体));Font font = new Font(bf, size, type);font.setColor(BaseColor.BLACK);font.setSize(size);return font;}// 页码事件类public static class PageNumberEvent extends PdfPageEventHelper {@Overridepublic void onEndPage(PdfWriter writer, Document document) {// 跳过首页(页码为1时不显示)if (writer.getPageNumber() == 1) {return;}PdfContentByte cb = writer.getDirectContent();try {// 设置字体,使用支持中文的字体(仍需设置,避免其他内容乱码)Font font = getFont(10, Font.NORMAL);// 设置字体到内容字节cb.setFontAndSize(font.getBaseFont(), font.getSize());// 计算页码位置(底部居中)// 从第2页开始,显示实际页码-1(如第2页显示1,第3页显示2)String pageNumber = String.valueOf(writer.getPageNumber() - 1);float x = (document.left() + document.right()) / 2;
// float y = document.bottom() - 15; // 设置底部float y = document.top(); // 设置顶部// 添加页码cb.beginText();cb.setTextMatrix(x, y);cb.showTextAligned(Element.ALIGN_CENTER, pageNumber, x, y, 0);cb.endText();} catch (Exception e) {e.printStackTrace();}}}// 水印事件类public static class WatermarkEvent extends PdfPageEventHelper {@Overridepublic void onEndPage(PdfWriter writer, Document document) {// 跳过首页(页码为1时不显示水印)if (writer.getPageNumber() == 1) {return;}PdfContentByte canvas = writer.getDirectContentUnder();try {// 设置水印字体Font font = getFont(12, Font.BOLD);// 设置水印文本String watermarkText = "检测报告";// 获取页面尺寸Rectangle pageSize = document.getPageSize();float width = pageSize.getWidth();float height = pageSize.getHeight();// 设置水印颜色和透明度canvas.saveState();// 创建 PdfGState 对象并设置透明度PdfGState gs = new PdfGState();gs.setFillOpacity(0.5f); // 填充透明度(0-1之间,0完全透明,1完全不透明)canvas.setGState(gs); // 将透明度应用到画布canvas.setRGBColorFill(200, 200, 200); // 灰色canvas.setFontAndSize(font.getBaseFont(), font.getSize());canvas.setTextMatrix(0, 0);// 设置水印旋转角度float angle = 30;// 计算水印位置并添加多个水印for (float y = -height / 2; y <= height * 1.5; y += 420) {for (float x = -width / 2; x <= width * 1.5; x += 300) {canvas.showTextAlignedKerned(Element.ALIGN_CENTER,watermarkText,x + width / 2,y + height / 2,angle);}}canvas.restoreState();} catch (Exception e) {e.printStackTrace();}}}}
实体类,水点字,就不写在同一个类下了
package com.wy.tools;public class Staff {private String id;private String name;private String age;private String work;private String pic;// 无参构造方法public Staff() {}// 有参构造方法public Staff(String id, String name, String age, String work, String pic) {this.id = id;this.name = name;this.age = age;this.work = work;this.pic = pic;}// Getter 和 Setter 方法public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAge() {return age;}public void setAge(String age) {this.age = age;}public String getWork() {return work;}public void setWork(String work) {this.work = work;}public String getPic() {return pic;}public void setPic(String pic) {this.pic = pic;}// 重写 toString 方法@Overridepublic String toString() {return "Study{" +"id='" + id + '\'' +", name='" + name + '\'' +", age='" + age + '\'' +", work='" + work + '\'' +", pic='" + pic + '\'' +'}';}
}