About itext

在网上看到java关于pdf的第三方库有名的是com.itextpdf的。

上git上查看,官网的意思是推荐itext7,而itext5只用于修复bug和安全了:

GitHub - itext/itextpdf: [DEPRECATED] Core Java Library + PDF/A, xtra and XML Worker. Only security fixes will be added — please use iText 7[DEPRECATED] Core Java Library + PDF/A, xtra and XML Worker. Only security fixes will be added — please use iText 7 - GitHub - itext/itextpdf: [DEPRECATED] Core Java Library + PDF/A, xtra and XML Worker. Only security fixes will be added — please use iText 7https://github.com/itext/itextpdf

所以,下面是以itext7进行的开发 :

GitHub - itext/itext7: iText 7 for Java represents the next level of SDKs for developers that want to take advantage of the benefits PDF can bring. Equipped with a better document engine, high and low-level programming capabilities and the ability to create, edit and enhance PDF documents, iText 7 can be a boon to nearly every workflow.https://github.com/itext/itext7官网:

The Leading PDF Library for Developers | iTexthttps://itextpdf.com/en

API Doc

Demo

好的,接下里开始上demo:

布局设定

分为title、table、detail三大类,如下用绿色框出来了:

按照这个设定封装对应的数据载体

然后编写工具类

接下测试即可。

工具类

imageUtil

用于读取base64的图片到byte数组

import org.bouncycastle.util.encoders.Base64;import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;public class ImageUtil {/*** 校验base64是否合法* @param base64* @return*/public static boolean safeCheckImgFile(String base64) {//check imageString regex = ",";String[] split = base64.split(regex);String imageBase64 = split[1];byte[] decode = Base64.decode(imageBase64);ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(decode);try {BufferedImage image = ImageIO.read(byteArrayInputStream);if (image != null && image.getWidth() > 0 && image.getHeight() > 0) {return true;}} catch (IOException e) {e.printStackTrace();}return false;/*Base64Encoder base64Encoder = new Base64Encoder();try {FileOutputStream fileImageOutputStream = new FileOutputStream("/data/temp/");BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileImageOutputStream);base64Encoder.decode(img, bufferedOutputStream);} catch (IOException e) {e.printStackTrace();}
*/}/*** 读取base64字符串,转换为bimage的ytes数组并返回* @param base64* @return*/public static byte[] readFromImage(String base64) {String regex = ",";String[] split = base64.split(regex);String imageBase64 = split[1];byte[] decode = Base64.decode(imageBase64);/*   ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(decode);try {BufferedImage image = ImageIO.read(byteArrayInputStream);
//            System.out.println(image);} catch (IOException e) {e.printStackTrace();}*/return decode;}
}

PdfUtil_v2

Pdf生成工具

import com.itextpdf.io.image.ImageDataFactory;
import com.itextpdf.kernel.colors.ColorConstants;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.borders.Border;
import com.itextpdf.layout.borders.SolidBorder;
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.TextAlignment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.text.SimpleDateFormat;
import java.util.LinkedList;
import java.util.List;public class PdfUtil_v2 {private Logger logger = LoggerFactory.getLogger(PdfUtil_v2.class);private MyPdfDocument pdfDocumnt;private String file_PATH;//文件绝对路径,包含文件名和后缀,如:I:\\jfqqqq\\test\\1.pdfprivate String font_PATH;private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");private String font_INTERNAL_PATH;public PdfUtil_v2(MyPdfDocument pdfDocumnt, String file_PATH, String font_PATH) {this.pdfDocumnt = pdfDocumnt;this.file_PATH = file_PATH;this.font_PATH = font_PATH;File directory = new File("src/main/resources");try {String resourcesPath = directory.getCanonicalPath();font_INTERNAL_PATH = resourcesPath + "/fonts/SimSun-01.ttf";logger.debug("配置的字体地址:{}, 工程预备的字体地址:{}", font_PATH, font_INTERNAL_PATH);} catch (IOException e) {e.printStackTrace();}}/*** 生成pdf,注意:会覆盖** @return*/public File generate() {Document document = null;try {createFilePath(file_PATH, false);PdfWriter pdfWriter = new PdfWriter(file_PATH);PdfDocument pdfDocument = new PdfDocument(pdfWriter);PdfFont font = getPdfFont();//PdfFontFactory.createFont(font_PATH);document = new Document(pdfDocument).setFont(font);writeHeader(document);writeStaticsGrid(document);staticsDetails(document);
//                document.close();return new File(file_PATH);
//            }} catch (Exception e) {e.printStackTrace();} finally {if (document != null) {document.close();}}return null;}private PdfFont getPdfFont() {PdfFont font = null;try {font = PdfFontFactory.createFont(font_PATH);} catch (IOException e) {logger.error("{} 字体文件不存在!即将采用更称默认字体,默认路径:{}", font_PATH, font_INTERNAL_PATH);synchronized (this) {font_PATH = font_INTERNAL_PATH;}}if (font == null) {try {font = PdfFontFactory.createFont(font_PATH);} catch (IOException e) {logger.error("{} 默认的字体文件不存在!即将采用itext7默认内置字体!不支持中文!", font_INTERNAL_PATH);}}if (font == null) {try {font = PdfFontFactory.createFont();} catch (IOException e) {logger.error("", e);e.printStackTrace();}}return font;}public void writeHeader(Document document) {Paragraph paragraphTitle = new Paragraph(pdfDocumnt.getTitle());paragraphTitle.setFontSize(22);Paragraph paragraphBatchName = new Paragraph("(" + pdfDocumnt.getSmallTitle() + ")");paragraphBatchName.setFontSize(12);Paragraph header = new Paragraph();header.setTextAlignment(TextAlignment.CENTER);header.add(paragraphTitle);header.add(paragraphBatchName);document.add(header);Table table = new Table(2);table.useAllAvailableWidth();Cell cell = new Cell(1, 1);cell.setBorder(Border.NO_BORDER);cell.setTextAlignment(TextAlignment.LEFT);cell.add(new Paragraph(pdfDocumnt.getTopLeft()));table.addCell(cell);cell = new Cell(1, 1);cell.setBorder(Border.NO_BORDER);cell.setTextAlignment(TextAlignment.RIGHT);cell.add(new Paragraph(pdfDocumnt.getTopRight()));table.addCell(cell);Border border = new SolidBorder(ColorConstants.RED, 2.0f);table.setBorderBottom(border);document.add(table);document.add(new Paragraph());//}public void writeStaticsGrid(Document document) {//开头描述Paragraph paragraphParent = new Paragraph();PdfTable pdfTable = pdfDocumnt.getTable();List<PdfTable.MyParagrah> beforeBegin = pdfTable.getBeforeBegin();for (PdfTable.MyParagrah begin : beforeBegin) {paragraphParent.add(new Paragraph(begin.getContent()).setFontColor(begin.getColor()));}document.add(paragraphParent);//统计表格LinkedList<PdfTable.Header> headers = pdfTable.getHeaders();Table table = new Table(headers.size());table.setWidth(500);for (PdfTable.Header header : headers) {table.addHeaderCell(header.getTitle());}List<PdfTable.MyLine> lines = pdfTable.getLines();for (PdfTable.MyLine line : lines) {for (PdfTable.Header header : headers) {table.addCell(new Paragraph(line.getCell(header.getCode()).getValue()));}}document.add(table);//空一行document.add(new Paragraph());//注意点描述List<String> pations = pdfTable.getPations();document.add(new Paragraph("注:").setFontColor(ColorConstants.RED));for (String pation : pations) {document.add(new Paragraph(pation).setFontColor(ColorConstants.RED));}}public void staticsDetails(Document document) {document.add(new Paragraph("报告详情").setFontSize(18));int questionNum = 0;List<PdfDetail> details = pdfDocumnt.getDetails();for (PdfDetail detail : details) {questionNum += 1;
//        addDetails(document, "问题1", "  " + checkValue, 12);addDetailsNextLine(document, "问题" + questionNum, "", 15, false);Table table = new Table(1);table.useAllAvailableWidth();List<PdfDetail.MyEntry> items = detail.getItems();for (PdfDetail.MyEntry item : items) {if (item.getEntryType() == PdfDetail.EntryType.STRING) {addDetailsInLine(table, item.getKey(), item.getVal(), null);} else if (item.getEntryType() == PdfDetail.EntryType.IMAGE) {addDetailsInLine(table, item.getKey(), "", null);Image image = readByBase64(item.getVal());image.setTextAlignment(TextAlignment.CENTER);image.setAutoScale(true);table.addCell(image);}}document.add(table);//这段代码注释了,这里演示的是直接给document增加图片
//            Image image = readByBase64(item.getVal());
//            image.setTextAlignment(TextAlignment.CENTER);
//            image.setAutoScale(true);
//            document.add(image);
//            document.add(new Paragraph(""));//增加一个空行}}private Image readByBase64(String base64) {byte[] bytes = ImageUtil.readFromImage(base64);Image image = new Image(ImageDataFactory.create(bytes));return image;}private void addDetailsInLine(Table table, String key, String value, Integer fontSize) {Paragraph paragraph = new Paragraph(key + ":  " + value);paragraph.setMarginLeft(20);if (fontSize != null) {paragraph.setFontSize(fontSize);}Cell cell = new Cell();cell.add(paragraph);cell.setBorder(Border.NO_BORDER);table.addCell(cell);}private void addDetailsNextLine(Document document, String key, String value, Integer fontSize, boolean useMaoHao) {String content = key + (useMaoHao ? ":" : "") + value;Paragraph paragraph = new Paragraph(content);paragraph.setMarginLeft(3);if (fontSize != null) {paragraph.setFontSize(fontSize);}document.add(paragraph);}public static File createFilePath(String path, boolean createFile) {File file = new File(path);if (!file.exists()) {if (file.isDirectory()) {file.mkdirs();} else {File parentFile = file.getParentFile();parentFile.mkdirs();try {if (createFile) {file.createNewFile();}} catch (IOException e) {e.printStackTrace();}
//                return parentFile;}}return file;}}

用于携带pdf数据的实体类

MyPdfDocument

pdf数据载体

import java.util.List;public class MyPdfDocument {private String title;private String smallTitle;private String topLeft;private String topRight;private PdfTable table;private List<PdfDetail> details;public MyPdfDocument() {}public String getTitle() {return title;}public String getSmallTitle() {return smallTitle;}public void setSmallTitle(String smallTitle) {this.smallTitle = smallTitle;}public void setTitle(String title) {this.title = title;}public String getTopLeft() {return topLeft;}public void setTopLeft(String topLeft) {this.topLeft = topLeft;}public String getTopRight() {return topRight;}public void setTopRight(String topRight) {this.topRight = topRight;}public PdfTable getTable() {return table;}public void setTable(PdfTable table) {this.table = table;}public List<PdfDetail> getDetails() {return details;}public void setDetails(List<PdfDetail> details) {this.details = details;}
}

PdfDetail

MyPdfDocument中的detail数据载体

import java.util.LinkedList;
import java.util.List;public class PdfDetail {private List<MyEntry> items = new LinkedList<>();public PdfDetail addItem(String key, String value) {items.add(new MyEntry(key, value));return this;}public PdfDetail addItem(String key, String value, EntryType type) {items.add(new MyEntry(key, value, type));return this;}public List<MyEntry> getItems() {return items;}public static enum EntryType{IMAGE, STRING}public static class MyEntry{private EntryType entryType = EntryType.STRING;private String key;private String val;public MyEntry(String key, String val) {this.key = key;this.val = val;}public MyEntry(String key, String val, EntryType type) {this.key = key;this.val = val;this.entryType = type == null ? entryType : type;}public EntryType getEntryType() {return entryType;}public String getKey() {return key;}public void setKey(String key) {this.key = key;}public String getVal() {return val;}public void setVal(String val) {this.val = val;}}
}

PdfTable

MyPdfDocument中的table数据载体

import com.itextpdf.kernel.colors.Color;import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;public class PdfTable {private List<MyParagrah> beforeBegin;private LinkedList<Header> headers;private List<MyLine> lines;private List<String> pations;public static class MyParagrah {private String content;private Color color;//ColorConstants.BLACKpublic MyParagrah(String content, Color color) {this.content = content;this.color = color;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}public Color getColor() {return color;}public void setColor(Color color) {this.color = color;}}public static class MyCell {private int headerCode;private String value;public MyCell(int headerCode, String value) {this.headerCode = headerCode;this.value = value;}public int getHeaderCode() {return headerCode;}public void setHeaderCode(int headerCode) {this.headerCode = headerCode;}public String getValue() {return value;}public void setValue(String value) {this.value = value;}}public static class MyLine {private Map<Integer, MyCell> cells = new HashMap<>();public MyLine addCell(MyCell cell) {cells.put(cell.getHeaderCode(), cell);return this;}public Map<Integer, MyCell> getCells() {return cells;}public MyCell getCell(int headerCode) {return cells.get(headerCode);}}public static class Header {private int code;private String title;public Header(int code, String title) {this.code = code;this.title = title;}public int getCode() {return code;}public void setCode(int code) {this.code = code;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}}public List<MyParagrah> getBeforeBegin() {return beforeBegin;}public void setBeforeBegin(List<MyParagrah> beforeBegin) {this.beforeBegin = beforeBegin;}public LinkedList<Header> getHeaders() {return headers;}public void setHeaders(LinkedList<Header> headers) {this.headers = headers;}public List<MyLine> getLines() {return lines;}public void setLines(List<MyLine> lines) {this.lines = lines;}public List<String> getPations() {return pations;}public void setPations(List<String> pations) {this.pations = pations;}
}

测试类

   @Testpublic void testHelper() {MyPdfDocument myPdfDocument = new MyPdfDocument();myPdfDocument.setTitle("jfqqqqq的监测报告");myPdfDocument.setSmallTitle("他很帅");myPdfDocument.setTopLeft("jfqqqq的个人管理平台");SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");myPdfDocument.setTopRight(simpleDateFormat.format(new Date()));PdfTable pdfTable = new PdfTable();List<PdfTable.MyParagrah> beforeBegins = new LinkedList<>() {{add(new PdfTable.MyParagrah("说点什么好呢,总的来说,这次的监测效果还算不错,我很努力,", ColorConstants.BLACK));add(new PdfTable.MyParagrah("值得嘉奖一下kkkkkkkkkkk值得嘉奖一下kkkkkkkkkkk值得嘉奖一下kkkkkkkkkkk值得嘉奖一下kkkkkkkkkkk值得嘉奖一下kkkkkkkkkkk", ColorConstants.RED));add(new PdfTable.MyParagrah("。嘉奖一下我自己!", ColorConstants.BLACK));}};pdfTable.setBeforeBegin(beforeBegins);LinkedList<PdfTable.Header> headers = new LinkedList<>() {{add(new PdfTable.Header(1, "序号"));add(new PdfTable.Header(2, "项目"));add(new PdfTable.Header(3, "努力"));add(new PdfTable.Header(4, "视力"));}};pdfTable.setHeaders(headers);List<PdfTable.MyLine> lines = new LinkedList<>();for (int i = 0; i < 5; i++) {PdfTable.MyLine line = new PdfTable.MyLine();line.addCell(new PdfTable.MyCell(1, "1")).addCell(new PdfTable.MyCell(2, "身高" + i)).addCell(new PdfTable.MyCell(3, "很努力,还行吧" + i)).addCell(new PdfTable.MyCell(4, "哈哈" + i));lines.add(line);}pdfTable.setLines(lines);pdfTable.setPations(new LinkedList<String>() {{add("1、这里是注释1");add("2、这里是注释2");}});myPdfDocument.setTable(pdfTable);List<PdfDetail> details = new ArrayList<>();for (int i = 0; i < 5; i++) {PdfDetail pdfDetail = new PdfDetail();String base64Image = "data:image/gif;base64,R0lGODlhDwAPAKECAAAAzMzM/wAAACwAAAAADwAPAAACIISPeQHsrZ5ModrLlN48CXF8m2iQ3YmmKqVlRtW4MLwWACH+H09wdGltaXplZCBieSBVbGVhZCBTbWFydFNhdmVyIQAAOw==";pdfDetail.addItem("身高", "身高" + i).addItem("努力", "很努力,还行吧" + i).addItem("视力", "哈哈" + i).addItem("截图", base64Image, PdfDetail.EntryType.IMAGE);details.add(pdfDetail);}myPdfDocument.setDetails(details);PdfUtil_v2 pdf = new PdfUtil_v2(myPdfDocument, "I:\\tobedelete\\asd.pdf", "F:\\anytest\\pdf\\src\\main\\resources\\fonts\\SimSun-01.ttf");pdf.generate();System.out.println("success!");}

字体文件

想要打印中文需要有中文字体支持的字体文件。可以到C:\Windows\Fonts中找一个中文字体文件给程序使用,或者自己从网上下载。

效果

附加

返回pdf文件时,响应头一般用这两种:

1. content-type:application/pdf
使用比如:

response.setContentType("application/pdf");

2. Content-Disposition:attachment; filename=aa.pdf

使用比如:
response.setHeader("Content-Disposition", "attachment; filename=" + new String((batchName + ".pdf").getBytes(),"utf-8"));

java使用itext7生成pdf相关推荐

  1. Java 使用iText7生成带页码的PDF文件(同时生成目录,但是不会合并两个PDF)

    一.效果图 1.带页码效果 2.目录效果 前言:Java 使用iText7生成带页码的PDF文件,同时生成目录PDF,但限于水平,暂时还在摸索合并两个PDF.不过看了一下,iText好像有生成目录的代 ...

  2. Itext7生成pdf最全api总结

    Itext7生成pdf最全api总结 最近使用itext7生成pdf被折磨到崩溃,一是官方文档不全,网上文章基本都是基于老版本api的,已经完全不适用itext7版本:二是itext7的api和css ...

  3. Android使用iText7生成PDF文件

    一:添加依赖 implementation 'com.itextpdf:itext7-core:7.1.13' 二:清单文件AndroidManifest.xml 添加权限 <uses-perm ...

  4. HTML生成PDF模板(Java iText+FreeMarker生成PDF(HTML转PDF))

    Java iText+FreeMarker生成PDF(HTML转PDF) 1.背景 在某些业务场景中,需要提供相关的电子凭证,比如网银/支付宝中转账的电子回单,签约的电子合同等.方便用户查看,下载,打 ...

  5. Java使用itext生成Pdf

    Java使用itext生成Pdf 背景 所需依赖 解决jpedal-lgpl jar包问题 示例代码 生成带图片的PDF(使用本地文件系统图片) 生成带图片的PDF(使用网络图片) 背景 在某些业务场 ...

  6. Java纯后端生成PDF格式报表的三种方案(包含echarts图表)

    最近做了一个奇葩的需求,研究了一下Java纯后端生成PDF报表的方案,顺便将研究的方案做个总结复盘,分享一下. 需求分析:Java后端定时任务统计汇总成报表数据,并生成PDF格式的报表文件,并通过邮件 ...

  7. 使用IText7 生成PDF文档

    itext7 生成pdf操作过于复杂,特别是封面.目录页码以及页眉页脚的处理需要基于事件处理,因此写了个简单的类库用于简化操作,只用关注文档内容的构建而无需关注其他: 代码地址: https://gi ...

  8. java用itextPDF生成PDF文件保存至本地并上传至ftp服务器

    标题java用itextPDF生成PDF文件保存至本地并上传至ftp服务器 所需jar :itext-asian-5.2.0.jar,itextpdf-5.5.5.jar,commons-net-3. ...

  9. java 生成字体文件,java使用itext生成pdf文件-设置字体,itextpdf,import com.l

    java使用itext生成pdf文件-设置字体,itextpdf,import com.limport com.lowagie.text.Document;import com.lowagie.tex ...

  10. java根据模板生成pdf文件并导出(iText)

    java根据模板生成pdf文件并导出 首先你的制作一个pdf模板: 1.先用word做出模板界面 2.文件另存为pdf格式文件 3.通过Adobe Acrobat pro软件打开刚刚用word转换成的 ...

最新文章

  1. 数字图像处理笔记一 - 图像采集(空间分辨率和幅度分辨率)
  2. 研究速递:预测学习——神经元高效运作的最佳策略
  3. 图集打包算法_UGUI打包图集工具-插件Simple Sprite Packer详解
  4. java调用存储过程 sql server_Java中调用SQL Server存储过程示例
  5. IntelliJ IDEA开发工具安装Scala插件使用
  6. CF1550E Stringforces
  7. “新基建”下,真正的数字化转型是这样的?有内味了
  8. c语言实验题水仙花数5359,《C语言程序设计》实验报告(实验1-12).doc
  9. 进制转化进10进制数
  10. 小程序实现分享图片_实现自己的图像识别,基于百度sdk的的图片识别项目
  11. Bootstrap 教程 之 Less 入门文档
  12. Next主题添加背景图片
  13. CKEditor5富文本编辑器在vue中的使用
  14. 两个运放制作加法器_初级模拟电路:8-2 加法与减法电路
  15. 3-24 浅谈多元正态分布的基本性质
  16. JavaScript 怎么自己手写一个Promise
  17. 硬件茶谈(B站up主爱上半导体)
  18. 小米电视怎么看cctv?安装小鲸电视免广告教程值得看
  19. MySQL优化之——函数
  20. 利用python声音处理库librosa提取声音信号的mfcc特征及特征融合

热门文章

  1. A. Death Note
  2. Dokcer从理论到实践----------Docker原理
  3. Solaris 11中的变化
  4. vuex的购物车效果 index.js
  5. 软件中反跟踪技术和软件调试
  6. Sql Server 中常用的字符串函数
  7. WinForm上显示gif动画
  8. 项目在云服务器上的绝对路径,项目在云服务器上的绝对路径
  9. mysql5.6怎样测试_Mysql5.6 字符集设置测试
  10. yolo使用webcam