「Java工具類」pdf導出工具類java導出pdf文件工具類
介紹語
本號主要是Java常用關鍵技術點,通用工具類的分享;以及springboot+springcloud+Mybatisplus+druid+mysql+redis+swagger+maven+docker等集成框架的技術分享;datax、kafka、flink等大數據處理框架的技術分享。文章會不斷更新,歡迎碼友關注點贊收藏轉發!
望各位碼友點擊關注,沖1000粉。后面會錄制一些視頻教程,圖文和視頻結合,比如:圖書介紹網站系統、搶購系統、大數據中臺系統等。技術才是程序猿的最愛,碼友們沖啊
如果碼友覺得代碼太長,可以從頭到尾快速掃射一遍,了解大概即可。覺得有用后再轉發收藏,以備不時之需。
正文:
pdf工具類,前面excel導出的時候一個碼有問有沒有pdf的工具類,我翻看了一下項目,沒找到。以前有一個項目是有pdf導出的,主要是導出一些發函有公章的文件,還有需求是導出報銷發票有公章等的文件,都是定制化的,耦合太大了,有些項目是要求導出網頁的內容,這個是前端直接導出pdf,根本不需要后端支持。所以我自己整理寫了一個工具類,拋磚引玉,有需求的碼友可以自己根據公司需求定制pdf的生成工具類。這里只是給出一個非常基本的工具類,僅提供導出,僅供參考。
使用例子
import org.junit.Test;
?
import java.util.ArrayList;
import java.util.List;
?
public class PdfUtilTest {
?
@Test
public void createTest(){
List<PdfChapter> pdfChapters = new ArrayList<>();
pdfChapters.add(createContent());
pdfChapters.add(createContent());
pdfChapters.add(createContent());
PdfUtil.getInstance().init().create("test14.pdf").chapters(pdfChapters).build();
}
?
private PdfChapter createContent(){
PdfChapter pdfChapter = new PdfChapter();
pdfChapter.setTitle("Pdf工具類");
pdfChapter.setOrder(1);
PdfSection section = new PdfSection();
section.setTitle("工具類例子1");
PdfText pdfText = new PdfText();
pdfText.setText("工具類內容內容");
pdfText.setImage(true);
pdfText.setImagePath("C:\\Users\\liangxn\\Desktop\\2021-11-06_002429.png");
section.getPdfTexts().add(pdfText);
pdfChapter.getSections().add(section);
return pdfChapter;
}
}
上面例子導出的pdf如下,有幾頁,每頁的內容是一樣的,含有一張圖片。這里提一下,圖片和內容的布局,不是那么簡單的,需要根據需求定制代碼。

工具類源碼:
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
?
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.List;
?
/**
* pdf工具類,主要是實現了導出功能。
* 使用itextpdf包實現
*/
public class PdfUtil {
?
private static final Logger logger = LoggerFactory.getLogger(PdfUtil.class);
?
// pdf大小,設置為A4紙大小
public static final Rectangle PAGE_SIZE = PageSize.A4;
// 設置內容距離紙張上右下左的距離
public static final float MARGIN_LEFT = 50;
public static final float MARGIN_RIGHT = 50;
public static final float MARGIN_TOP = 50;
public static final float MARGIN_BOTTOM = 50;
// 空格的間距大小
public static final float SPACING = 20;
// 標題對齊方式: 0表示left,1表示center
public static final int TITLE_ALIGNMENT = 1;
?
?
private static volatile PdfUtil instance = null;
// pdf文檔
private Document document = null;
//文章標題字體
private Font _chapterFont = null;
//小節標題字體
private Font _sectionFont = null;
//內容字體
private Font _textFont = null;
?
private PdfUtil() {
}
?
//DCL (Double Check Lock 雙端撿鎖機制)
public static PdfUtil getInstance() {
if (instance == null) {
synchronized (PdfUtil.class) {
if (instance == null) {
instance = new PdfUtil();
}
}
}
return instance;
}
?
/**
* 初始化字體
*/
protected PdfUtil init() {
// 默認設置
_chapterFont = createFont(20, Font.BOLD, new BaseColor(0, 0, 255));
_sectionFont = createFont(16, Font.BOLD, new BaseColor(0, 0, 255));
_textFont = createFont(10, Font.NORMAL, new BaseColor(0, 0, 0));
return instance;
}
?
/**
* 初始化字體
*/
protected PdfUtil init(Font chapterFont, Font sectionFont, Font textFont) {
// 使用自定義的字體
_chapterFont = chapterFont;
_sectionFont = sectionFont;
_textFont = textFont;
return instance;
}
?
/**
* 創建pdf文件
*
* @param fileName 文件(全路徑文件名)
*/
protected PdfUtil create(String fileName) {
File file = new File(fileName);
document = new Document(PAGE_SIZE, MARGIN_LEFT, MARGIN_RIGHT, MARGIN_TOP, MARGIN_BOTTOM);
FileOutputStream out = null;
try {
out = new FileOutputStream(file);
PdfWriter.getInstance(document, out);
} catch (FileNotFoundException e) {
logger.error("創建pdf文件異常", e);
} catch (DocumentException e) {
logger.error("創建pdf文件錯誤", e);
}
// 打開文檔準備寫入內容
document.open();
return instance;
}
?
protected PdfUtil chapters(List<PdfChapter> pdfChapters) {
try {
for (PdfChapter pdfChapter : pdfChapters) {
Chapter chapter = writeChapter(pdfChapter);
for (PdfSection pdfSection : pdfChapter.getSections()) {
Section section = writeSection(chapter, pdfSection);
for (PdfText pdfText : pdfSection.getPdfTexts()) {
if(pdfText.isImage()){
writeImage(pdfText.getImagePath());
}
?
if(pdfText.getText() != null){
section.add(writePhrase(pdfText.getText()));
}
}
}
document.add(chapter);
}
} catch (DocumentException e) {
e.printStackTrace();
}
?
return instance;
}
?
protected void build(){
closeDocument();
}
?
/**
* 寫章節
*
* @param pdfChapter
*/
private Chapter writeChapter(PdfChapter pdfChapter) {
Paragraph chapterTitle = new Paragraph(pdfChapter.getTitle(), _chapterFont);
chapterTitle.setAlignment(TITLE_ALIGNMENT);
Chapter chapter = new Chapter(chapterTitle, pdfChapter.getOrder());
chapter.setNumberDepth(pdfChapter.getDepth());
return chapter;
}
?
/**
* 寫片段
*
* @param chapter
* @param pdfSection
* @return
*/
private Section writeSection(Chapter chapter, PdfSection pdfSection) {
Section section = null;
if (chapter != null) {
Paragraph sectionTitle = new Paragraph(pdfSection.getTitle(), _sectionFont);
sectionTitle.setSpacingBefore(SPACING);
section = chapter.addSection(sectionTitle);
section.setNumberDepth(pdfSection.getDepth());
}
return section;
}
?
/**
* 寫內容
*
* @param text
*/
private Phrase writePhrase(String text) {
return new Paragraph(text, _textFont);
}
?
/**
* 寫圖片
*
* @param image
*/
private void writeImage(String image) {
try {
//圖片1
Image image1 = Image.getInstance(image);
//將圖片1添加到pdf文件中
document.add(image1);
} catch (IOException e) {
logger.error("寫入圖片異常", e);
} catch (DocumentException e) {
logger.error("寫入圖片錯誤", e);
}
}
?
/**
* 功能: 返回支持中文的字體---仿宋
* <p>
* simfang.ttf 仿宋常規
* <p>
* simhei.ttf 黑體常規
*
* @param size 字體大小
* @param style 字體風格
* @param color 字體 顏色
* @return 字體格式
*/
private Font createFont(float size, int style, BaseColor color) {
BaseFont baseFont = null;
try {
// simfang.ttf文件必須放在class類文件所有的包路徑下
URL resource = PdfUtil.class.getClassLoader().getResource("simfang.ttf");
if (resource == null) {
throw new MyAppRunException("無simfang.ttf字體文件");
}
logger.info("加載simfang.ttf字體, 路徑:{}", resource.getPath());
baseFont = BaseFont.createFont(resource.getPath(), BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
} catch (DocumentException e) {
logger.error("加載字體錯誤", e);
} catch (IOException e) {
logger.error("加載字體錯誤", e);
}
return new Font(baseFont, size, style, color);
}
?
/**
* 最后關閉PDF文檔
*/
private void closeDocument() {
if (document != null) {
// 執行關閉時文件會自動保存
document.close();
logger.info("文件已保存");
}
}
?
}
實體類:
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
public class PdfChapter {
private String title;
/**
* 章節序列號
*/
private int order;
/**
* 章節的層級深度 設值=1 表示帶序號 1.章節一;1.1小節一...,設值=0表示不帶序號
*/
private int depth = 0;
private List<PdfSection> sections = new ArrayList<>();
}
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
public class PdfSection {
private String title;
/**
* 否帶序號 設值=1 表示帶序號 1.章節一;1.1小節一...,設值=0表示不帶序號
*/
private int depth = 1;
private List<PdfText> pdfTexts = new ArrayList<>();
}
import lombok.Data;
@Data
public class PdfText {
private String text;
private String imagePath;
private boolean isImage = false;
}
其他類:
/**
* 通用異常類
*/
public class MyAppRunException extends RuntimeException {
public MyAppRunException(String message) {
super(message);
}
public MyAppRunException(String message, Throwable cause) {
super(message, cause);
}
public MyAppRunException(Throwable cause) {
super(cause);
}
protected MyAppRunException(String message,
Throwable cause,
boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
maven依賴
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13.2</version>
</dependency>
外話,pdf的需求基本都是需要定制的,不是一個工具類能搞定的。這里給出處理pdf的另一個包,這個包是apache的包,對于讀pdf非常好用。需要定制pdf導出的話,還是需要多了解這兩個包,然后定制自己的工具類。
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.24</version>
<type>bundle</type> <!-- 要使用bundle需要先依賴一個plugin,自行百度 -->
</dependency>
鄙人編碼十年多,在項目中也積累了一些工具類,很多工具類在每個項目都有在用,很實用。大部分是鄙人封裝的,有些工具類是同事封裝的,有些工具類已經不記得是ctrl+c的還是自己封裝的了,現在有空就會總結項目中大部分的工具類,分享給各位碼友。如果文章中涉及的代碼有侵權行為請通知鄙人處理。
計劃是先把工具類整理出來,正所謂工欲善其事,必先利其器。項目中不管是普通單體項目還是多模塊maven項目或是分布式微服務,一部分功能模塊都是可以重用的,工具類模塊就是其中之一。

浙公網安備 33010602011771號