Java實(shí)現(xiàn)給PDF文件增加背景圖的操作指南
說明:本文介紹在使用代碼生成 PDF 文件的基礎(chǔ)上,如何給生成的的 PDF 文件增加背景圖。生成 PDF 文件參看下面這篇博客。
思路
思路是在生成后的 PDF 文件基礎(chǔ)上操作,不是在生成 PDF 的模板文件上實(shí)現(xiàn)。
如下,是前文中生成的 PDF 文件。

將下面這張圖作為文件背景放入到 PDF 文件中

實(shí)現(xiàn)一
如下,在原生成 PDF 文件的基礎(chǔ)上,增加設(shè)置背景的代碼
@PostMapping("/pdf")
public byte[] pdf() throws IOException {
// 構(gòu)建響應(yīng)頭
String fileName = "example.pdf";
String encodedFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setContentDispositionFormData("attachment", encodedFileName);
// 生成PDF文件
byte[] pdf = pdfService.pdf();
// PDF文件
File pdfFile = FileUtil.createTempFile("demo", ".pdf", null, true);
FileUtil.writeBytes(pdf, pdfFile);
// 背景圖片
ClassPathResource resource = new ClassPathResource("template/picture.jpg");
File pictureFile = FileUtil.createTempFile("picture", ".jpg", null, true);
FileUtil.writeBytes(resource.getInputStream().readAllBytes(), pictureFile);
// 添加背景圖片,獲取添加背景后的PDF文件
byte[] bytes = addBackground1(pdfFile, pictureFile);
// 返回
return ResponseEntity.ok()
.headers(headers)
.body(bytes).getBody();
}
其中,添加背景圖片方法代碼如下:
/**
* 添加背景圖片
*
* @param pdfFile PDF文件
* @param pictureFile 背景圖片
* @return 添加背景后的PDF文件
*/
private byte[] addBackground1(File pdfFile, File pictureFile) {
// 定義輸出流,存添加完背景的PDF文件
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
// 透明度設(shè)置為0.2
float transparency = 0.2f;
// 加載PDF文件
try (PDDocument document = PDDocument.load(pdfFile)) {
// 加背景圖片
PDImageXObject backgroundImage = PDImageXObject.createFromFileByExtension(pictureFile, document);
// 創(chuàng)建透明度配置
PDExtendedGraphicsState graphicsState = new PDExtendedGraphicsState();
graphicsState.setNonStrokingAlphaConstant(transparency);
// 遍歷每一頁
for (PDPage page : document.getPages()) {
// 獲取頁面尺寸(單位:點(diǎn),1點(diǎn)=1/72英寸)
float pageWidth = page.getMediaBox().getWidth();
float pageHeight = page.getMediaBox().getHeight();
// 創(chuàng)建內(nèi)容流(追加模式,放在最底層)
try (PDPageContentStream contentStream = new PDPageContentStream(
document, page, PDPageContentStream.AppendMode.PREPEND, true)) {
// 應(yīng)用透明度配置
contentStream.setGraphicsStateParameters(graphicsState);
// 繪制背景圖(鋪滿整個(gè)頁面)
contentStream.drawImage(backgroundImage, 0, 0, pageWidth, pageHeight);
}
}
// 保存修改后的PDF
document.save(outputStream);
// 以字節(jié)數(shù)組的形式返回加完背景的PDF文件
return outputStream.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
return new byte[0];
}
這種方式所需下面這個(gè)依賴
<dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox</artifactId> <version>2.0.27</version> </dependency>
實(shí)現(xiàn)二
還可以用下面這段代碼
/**
* 添加背景圖片
*
* @param pdfFile PDF文件
* @param pictureFile 背景圖片
* @return 添加背景后的PDF文件
*/
private byte[] addBackground2(File pdfFile, File pictureFile) throws DocumentException, IOException {
// 定義輸出流,存添加完背景的PDF文件
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
// 透明度設(shè)置為0.2
float transparency = 0.2f;
PdfReader reader = null;
PdfStamper stamper = null;
try {
reader = new PdfReader(FileUtil.readBytes(pdfFile));
stamper = new PdfStamper(reader, outputStream);
Image backgroundImage = Image.getInstance(FileUtil.readBytes(pictureFile));
// 創(chuàng)建透明度配置對象
PdfGState gState = new PdfGState();
gState.setFillOpacity(transparency);
int totalPages = reader.getNumberOfPages();
for (int i = 1; i <= totalPages; i++) {
// 直接通過PdfReader獲取頁面尺寸
Rectangle pageSize = reader.getPageSize(i);
float pageWidth = pageSize.getWidth();
float pageHeight = pageSize.getHeight();
backgroundImage.scaleToFit(pageWidth, pageHeight);
backgroundImage.setAbsolutePosition(0, 0);
PdfContentByte content = stamper.getUnderContent(i);
// 應(yīng)用透明度設(shè)置
content.setGState(gState);
content.addImage(backgroundImage);
}
stamper.close();
reader.close();
return outputStream.toByteArray();
} catch (IOException | DocumentException e) {
e.printStackTrace();
} finally {
if (stamper != null) {
stamper.close();
}
if (reader != null) {
reader.close();
}
}
return new byte[0];
}
這段代碼所需下面這個(gè)依賴
<dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <version>5.5.13.3</version> </dependency>
效果
兩種方式,實(shí)現(xiàn)的效果如下:
(實(shí)現(xiàn)一)

(實(shí)現(xiàn)二)

一個(gè)自適應(yīng)了 PDF 文件的尺寸,一個(gè)沒有,如果添加的背景圖片(版權(quán)標(biāo)識、企業(yè) logo)尺寸合適的話,這兩種實(shí)現(xiàn)方式?jīng)]有大的區(qū)別。
作為開發(fā)者,可以根據(jù)當(dāng)前項(xiàng)目中是否已引入上面哪個(gè)依賴,來選擇使用哪種實(shí)現(xiàn)方式。
到此這篇關(guān)于Java實(shí)現(xiàn)給PDF文件增加背景圖的操作指南的文章就介紹到這了,更多相關(guān)Java PDF文件增加背景圖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java調(diào)用百度定位api服務(wù)獲取地理位置示例
java調(diào)用百度定位api服務(wù)獲取地理位置示例,大家參考使用吧2013-12-12
Java?Playwright實(shí)現(xiàn)瀏覽器最大化
Playwright?是一個(gè)用于自動(dòng)化?Web?應(yīng)用測試的現(xiàn)代工具,支持多種語言(包括?Java)及多個(gè)瀏覽器,本文主要介紹了Java如何使用Playwright實(shí)現(xiàn)瀏覽器最大化,需要的可以參考下2024-12-12
Java中的重寫(Override)與重載(Overload)詳解
這篇文章主要介紹了Java中的重寫(Override)與重載(Overload)使用方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-05-05
Java實(shí)現(xiàn)中序表達(dá)式的實(shí)例代碼
這篇文章主要介紹了Java實(shí)現(xiàn)中序表達(dá)式的實(shí)例代碼,需要的朋友可以參考下2018-08-08
總結(jié)Java常用加解密方法AES?SHA1?md5
這篇文章主要為大家介紹了Java常用加密方法AES?SHA1?md5總結(jié)及示例demo,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06
Java 中POI 導(dǎo)入EXCEL2003 和EXCEL2007的實(shí)現(xiàn)方法
這篇文章主要介紹了Java 中POI 導(dǎo)入EXCEL2003 和EXCEL2007的實(shí)現(xiàn)方法的相關(guān)資料,希望通過本文大家能掌握理解這種方法,需要的朋友可以參考下2017-09-09
Java8接口中引入default關(guān)鍵字的本質(zhì)原因詳析
Default方法是在java8中引入的關(guān)鍵字,也可稱為Virtual extension methods—虛擬擴(kuò)展方法,這篇文章主要給大家介紹了關(guān)于Java8接口中引入default關(guān)鍵字的本質(zhì)原因,需要的朋友可以參考下2022-01-01

