java生成pdf_Java实现PDF文件生成并且打印pdf文件 demo
## Java實(shí)現(xiàn)PDF生成并且打印pdf文件(附demo)
#### 目錄:
0. 效果預(yù)覽
1. 準(zhǔn)備環(huán)境
2. Java如何調(diào)用打印機(jī)進(jìn)行打印
3. Java如何生成pdf打印文件
4. 實(shí)現(xiàn)pdf內(nèi)數(shù)據(jù)動(dòng)態(tài)填充(可按需求改變數(shù)據(jù),有一個(gè)模板就行)
##### 效果預(yù)覽:
- 說(shuō)明:以下是根據(jù)不同用戶數(shù)據(jù)和自己生成的pdf模板,動(dòng)態(tài)生成的pdf文件,可直接調(diào)用打印機(jī)打印。
- 數(shù)據(jù)可從數(shù)據(jù)庫(kù)動(dòng)態(tài)獲取并且填充

##### 環(huán)境準(zhǔn)備:
1. java標(biāo)準(zhǔn)開發(fā)環(huán)境
2. 打印機(jī)一臺(tái)(確保已和設(shè)備連接),測(cè)試的時(shí)候要用,開發(fā)沒(méi)有打印機(jī)也行
3. 相關(guān)jar包
- pdfbox
- itextpdf
- commons-logging.jar
##### 實(shí)現(xiàn)Java調(diào)用打印機(jī)進(jìn)行打印文件
之前寫過(guò)一篇,多種方式,有興趣的可以看看。[點(diǎn)擊這里查看](https://blog.csdn.net/JavaBuilt/article/details/81322086)
這里使用的是PDFBox方式實(shí)現(xiàn)打印,引入PDFBox.jar和commons-logging.jar,嫌麻煩地可以在文章底部下載demo,我把所有相關(guān)的jar,源碼都放進(jìn)去了
傳入文件對(duì)象即可進(jìn)行打印,**打印前請(qǐng)確認(rèn)打印機(jī)是否正常連接!!!!**
```java
/**
* 打印實(shí)現(xiàn)類
* createTime:2018-08-01
*
* @author Jason
*
*/
public final class JHPrintor {
/** 日志記錄對(duì)象 */
private static Logger log = Logger.getLogger(JHPrintor.class);
/** 私有構(gòu)造器 */
private JHPrintor() {
}
/**
* 打印pdf文件
*
* @param file 需打印的pdf文件
*/
public static void print(File file) {
try {
PDDocument document = PDDocument.load(file);
// 加載成打印文件
PDFPrintable printable = new PDFPrintable(document,Scaling.ACTUAL_SIZE);
PrinterJob job = PrinterJob.getPrinterJob();
job.setPrintable(printable);
job.defaultPage();
job.print();
} catch (InvalidPasswordException e) {
log.error("打印異常:文檔初始化密碼失敗!");
PromptUtil.error("初始化文檔密碼異常,打印失敗!");
e.printStackTrace();
} catch (IOException e) {
log.error("打印異常!");
PromptUtil.error("打印異常,請(qǐng)關(guān)閉后重試!");
e.printStackTrace();
} catch (PrinterException e) {
log.error("未正常連接打印機(jī)");
PromptUtil.error("請(qǐng)檢查打印機(jī)是否正常連接!");
e.printStackTrace();
}
}
}
```
#### Java如何生成pdf文件
這個(gè)比較復(fù)雜,涉及到單元格,表,段落,標(biāo)題等內(nèi)容
慢慢來(lái),一步一步講解一下
```java
/**
* 生成pdf文件的工具類
* createTime:2018-08-01
*
* @author Jason
*
*/
public class JHCreatePDF {
// 日志記錄對(duì)象
public static Logger log = Logger.getLogger(JHCreatePDF.class);
// 系統(tǒng)字體文件在 Windows/Fonts目錄下,將其粘到src下即可
public static final String CHARACTOR_FONT_CH_FILE = "/SIMSUN.TTC,1"; //宋體 常規(guī)
// 紙張尺寸
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;
// 文件對(duì)象
private Document document = null;
private File file;
/**
* 功能:創(chuàng)建導(dǎo)出數(shù)據(jù)的目標(biāo)文檔
* @return
*/
public void createDocument() {
// 創(chuàng)建pdf文件
FileOutputStream out = null;
document = new Document(PAGE_SIZE, MARGIN_LEFT, MARGIN_RIGHT, MARGIN_TOP, MARGIN_BOTTOM);
try {
file = File.createTempFile("temp", ".pdf");
} catch (IOException e1) {
Log.error("創(chuàng)建臨時(shí)打印文件失敗!");
PromptUtil.error("創(chuàng)建臨時(shí)打印文件失敗,請(qǐng)關(guān)閉重試");
e1.printStackTrace();
return; // 結(jié)束后續(xù)運(yùn)行
}
try {
out = new FileOutputStream(file);
PdfWriter.getInstance(document, out);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (DocumentException e) {
e.printStackTrace();
}
// 打開文檔準(zhǔn)備寫入內(nèi)容
document.open();
}
/**
* 功能 創(chuàng)建PDF文檔中的章節(jié)
* @param title 章節(jié)標(biāo)題
* @param chapterNum 章節(jié)序列號(hào)
* @param alignment 0表示align=left,1表示align=center
* @param numberDepth 章節(jié)是否帶序號(hào) 設(shè)值=1 表示帶序號(hào) 1.章節(jié)一;1.1小節(jié)一...,設(shè)值=0表示不帶序號(hào)
* @param font 字體格式
* @return Chapter章節(jié)
*/
public static Chapter createChapter(String title, int chapterNum, int alignment, int numberDepth, Font font) {
Paragraph chapterTitle = new Paragraph(title, font);
chapterTitle.setAlignment(alignment);
Chapter chapter = new Chapter(chapterTitle, chapterNum);
chapter.setNumberDepth(numberDepth);
return chapter;
}
/**
* 功能:創(chuàng)建某指定章節(jié)下的小節(jié)
* @param chapter 指定章節(jié)
* @param title 小節(jié)標(biāo)題
* @param font 字體格式
* @param numberDepth 小節(jié)是否帶序號(hào) 設(shè)值=1 表示帶序號(hào) 1.章節(jié)一;1.1小節(jié)一...,設(shè)值=0表示不帶序號(hào)
* @return section在指定章節(jié)后追加小節(jié)
*/
public static Section createSection(Chapter chapter, String title, Font font, int numberDepth) {
Section section = null;
if(chapter != null) {
Paragraph sectionTitle = new Paragraph(title, font);
sectionTitle.setSpacingBefore(SPACING);
section = chapter.addSection(sectionTitle);
section.setNumberDepth(numberDepth);
}
return section;
}
/**
* 功能:向PDF文檔添加chunk
*
* @param text
* @param font
* @return
*/
public static Chunk createChunk(String text,Font font) {
return new Chunk(text, font);
}
/**
* 功能:向PDF文檔中添加的內(nèi)容 (核心句子)
* @param text 內(nèi)容
* @param font 內(nèi)容對(duì)應(yīng)的字體
* @return phrase 指定字體格式的內(nèi)容
*/
public static Phrase createPhrase(String text,Font font) {
Phrase phrase = new Paragraph(text,font);
return phrase;
}
/**
* 最后關(guān)閉PDF文檔
*/
public void closeDocument() {
if(document != null) {
document.close();
}
}
/**
* 讀PDF文件,使用了pdfbox開源項(xiàng)目
* @param fileName
*/
public void readPDF(String fileName) {
File file = new File(fileName);
FileInputStream in = null;
try {
in = new FileInputStream(fileName);
// 新建一個(gè)PDF解析器對(duì)象
PDFParser parser = new PDFParser((RandomAccessRead) in);
// 對(duì)PDF文件進(jìn)行解析
parser.parse();
// 獲取解析后得到的PDF文檔對(duì)象
PDDocument pdfdocument = parser.getPDDocument();
// 新建一個(gè)PDF文本剝離器
PDFTextStripper stripper = new PDFTextStripper();
// 從PDF文檔對(duì)象中剝離文本
String result = stripper.getText(pdfdocument);
System.out.println("PDF文件的文本內(nèi)容如下:");
System.out.println(result);
} catch (Exception e) {
System.out.println("讀取PDF文件" + file.getAbsolutePath() + "生失敗!" + e);
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e1) {
}
}
}
}
/**
* 獲取臨時(shí)文件
*
* @return
*/
public File getTempFile() {
if(file == null);
log.error("生成的臨時(shí)文件失敗");
return file;
}
}
```
這是生成pdf的一個(gè)工具類,代碼注釋寫的比較詳細(xì),直接看就行
**主要講一下需要注意的地方:**

文件字體:必須有字體文件
```java
// 系統(tǒng)字體文件在 Windows/Fonts目錄下,將其粘到src下即可
public static final String CHARACTOR_FONT_CH_FILE = "/SIMSUN.TTC,1"; //宋體 常規(guī)
```
紙張尺寸:設(shè)置A4,有別的需求可自行設(shè)置
```java
// 紙張尺寸
public static final Rectangle PAGE_SIZE = PageSize.A4;
```
上下左右邊距:就是文件內(nèi)容距離上下左右四條邊的距離,可自行根據(jù)需求設(shè)置
```java
// 邊距
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;
```
生成pdf時(shí),必須最先調(diào)用方法生成document對(duì)象,并向里寫數(shù)據(jù)
```java
void createDocument()
```
pdf內(nèi)容寫完時(shí),最后調(diào)用,關(guān)閉document對(duì)象
```java
void closeDocument()
```
##### 如何生成模板并填充數(shù)據(jù)
舉個(gè)例子
比如生成這個(gè)樣子:

```java
private void writeVA(Chapter chapter) {
// -------------------------這里開始 到下面寫你自己的數(shù)據(jù)對(duì)象解析邏輯 --------
VisualAcuity[] vaArr = {leftPreVA,leftSufVA,rightPreVA,rightSufVA,doublePreVA,doubleSufVA} ;
initVA(); // 實(shí)例化對(duì)象
ListvaList = ppe.getVaList();
if (vaList != null&& vaList.size() > 0) {
for (VisualAcuity va:vaList
) {
fillVisualAcuity(va);
}
}
// --------------------------end -------------------------------------
// 表格標(biāo)題
JHCreatePDF.createSection(chapter,"視銳度:",titleFont,0);
// 生成一個(gè)section對(duì)象
Section section = JHCreatePDF.createSection(chapter, null, textFont, 0);
// 創(chuàng)建表格對(duì)象, 按需求初始化4列
PdfPTable table = new PdfPTable(4);
PdfPCell cell5 = null;
// 第一行 表頭
cell5 = new PdfPCell(JHCreatePDF.createPhrase(null,textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
cell5.setColspan(2);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase("單字母視銳度",textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase("行字母視銳度",textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase("擁擠字母視銳度",textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
// 第二行
cell5 = new PdfPCell(JHCreatePDF.createPhrase("左眼",textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
cell5.setPaddingTop(7);
cell5.setRowspan(2);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase("訓(xùn)練前",textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase("填寫你的數(shù)據(jù)”,textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase(leftPreVA.getLineLetter(),textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase(leftPreVA.getCrowdLetter(),textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase("訓(xùn)練后",textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase(leftSufVA.getSingleLetter(),textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase(leftSufVA.getLineLetter(),textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase(leftSufVA.getCrowdLetter(),textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
// 第三行
cell5 = new PdfPCell(JHCreatePDF.createPhrase("右眼",textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
cell5.setPaddingTop(7);
cell5.setRowspan(2);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase("訓(xùn)練前",textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase(rightPreVA.getSingleLetter(),textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase(rightPreVA.getLineLetter(),textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase(rightPreVA.getCrowdLetter(),textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase("訓(xùn)練后",textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase(rightSufVA.getSingleLetter(),textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase(rightSufVA.getLineLetter(),textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase(rightSufVA.getCrowdLetter(),textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
// 第四行
cell5 = new PdfPCell(JHCreatePDF.createPhrase("雙眼",textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
cell5.setRowspan(2);
cell5.setPaddingTop(7);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase("訓(xùn)練前",textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase(doublePreVA.getSingleLetter(),textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase(doublePreVA.getLineLetter(),textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase(doublePreVA.getCrowdLetter(),textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase("訓(xùn)練后",textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase(doubleSufVA.getSingleLetter(),textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase(doubleSufVA.getLineLetter(),textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
cell5 = new PdfPCell(JHCreatePDF.createPhrase(doubleSufVA.getCrowdLetter(),textFont));
cell5.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell5);
table.setWidthPercentage(100); // 填充度,百分百填充
section.add(table);
}
```
為什么說(shuō)是動(dòng)態(tài)呢?? 因?yàn)檫@里使用的只是數(shù)據(jù)對(duì)象模型,只要是這種模型,不同數(shù)據(jù)的對(duì)象就會(huì)填充不同的數(shù)據(jù),生成內(nèi)容不同的pdf!
**整個(gè)流程涉及到pdf如何存儲(chǔ),打印,以及銷毀!
下面說(shuō)說(shuō)我的思路:**
我將生成的pdf存放在系統(tǒng)的臨時(shí)文件夾中
生成下一個(gè)打印文件時(shí),定時(shí)檢測(cè)pdf文件數(shù)量,然后刪除之前生產(chǎn)的pdf文件
到這里,基本打印,生產(chǎn),數(shù)據(jù)填充,文件銷毀基本寫完
下載demo源碼,包含所有相關(guān)jar包,以及工具類和完整代碼
點(diǎn)擊這里下載
總結(jié)
以上是生活随笔為你收集整理的java生成pdf_Java实现PDF文件生成并且打印pdf文件 demo的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: python参数顺序 元组 字典_pyt
- 下一篇: java 访问私有成员,在Java中访问