Java根據(jù)前端傳回的圖片生成pdf并且加密碼和水印
更新時間:2025年01月23日 09:01:58 作者:小七蒙恩
這篇文章主要為大家詳細介紹了java如何根據(jù)前端傳回的png圖片數(shù)組,后端加水印加密碼生成pdf并返回給前端,感興趣的小伙伴可以參考一下
場景
當前需求,前端通過html2canvas將頁面報表生成圖片下載,可以仍然不滿意。
需要java后端將前端傳過來的圖片生成pdf,并且加密碼加水印。
重點
pdf使用A4大小,但是要考慮。根據(jù)A4寬高縮放圖片后,圖片仍然大于A4長度,此時要對圖片進行裁剪(2頁,3頁…)
maven依賴
<!-- pdf文件水印添加 -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext7-core</artifactId>
<version>7.1.4</version>
<type>pom</type>
</dependency>
controller
@PostMapping("/addMarkAndPasswordPdf")
@ApiOperation(value = "文件處理-增加水印及密碼--入?yún)槲募?, notes = "")
public void addMarkAndPasswordPdf(@RequestParam("fileStream") MultipartFile[] fileStreams,@RequestParam("filePdfName")String filePdfName, HttpServletRequest request, HttpServletResponse response) {
Calendar calendar = Calendar.getInstance();
String date = calendar.get(Calendar.YEAR) + "-" + (calendar.get(Calendar.MONTH) + 1);
SysUserEntity uc = (SysUserEntity) request.getAttribute("UC");
SysUserEntity uc1 = userService.getUserByCode(uc.getUserCode());
fileProcessService.fileProcessPdf(fileStreams,filePdfName,uc1,response);
}
service
@Override
public void fileProcessPdf(MultipartFile[] imageFiles,String filePdfName, SysUserEntity uc, HttpServletResponse response) {
response.setHeader("Content-disposition", "attachment;filename=" + filePdfName);
// 直接用瀏覽器或者用postman
response.setContentType("application/pdf");
response.setCharacterEncoding("utf-8");
try {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
// 創(chuàng)建PDF文檔 加密PDF文檔
PdfWriter writer = new PdfWriter(byteArrayOutputStream,new WriterProperties().setStandardEncryption(
// 用戶密碼
uc.getPassword().getBytes(),
// 所有者密碼
uc.getPassword().getBytes(),
// 允許的權(quán)限
EncryptionConstants.ALLOW_PRINTING | EncryptionConstants.ALLOW_COPY,
// 加密標準
EncryptionConstants.STANDARD_ENCRYPTION_128
));
PdfDocument pdfDoc = new PdfDocument(writer);
Document document = new Document(pdfDoc);
// 讀取原始圖片.按照A4拆分圖片,放到pdf
for(MultipartFile imageFile: imageFiles){
BufferedImage originalImage = ImageIO.read(imageFile.getInputStream());
float maxHeight = (PageSize.A4.getHeight()/PageSize.A4.getWidth())*originalImage.getWidth();
ArrayList<BufferedImage> cropImageList = cropImageByMaxHeight(originalImage, (int) maxHeight);
for (BufferedImage bufferedImage : cropImageList) {
// 添加圖片
PdfPage page = pdfDoc.addNewPage();
ByteArrayOutputStream ImageOutputStream = new ByteArrayOutputStream();
ImageIO.write(bufferedImage, "png", ImageOutputStream);
ImageData imageData = ImageDataFactory.create(ImageOutputStream.toByteArray());
com.itextpdf.layout.element.Image image = new com.itextpdf.layout.element.Image(imageData);
image.setHorizontalAlignment(HorizontalAlignment.CENTER);
document.add(image);
ImageOutputStream.close();
// 循環(huán)為頁設(shè)置水印
setPageWatermark(page, pdfDoc,uc.getCname() + ", " + uc.getDeptTwo(),140);
}
}
// 關(guān)閉文檔以不再寫入內(nèi)容
document.close();
pdfDoc.close();
writer.close();
// 將PDF寫入響應(yīng)輸出流
response.getOutputStream().write(byteArrayOutputStream.toByteArray());
response.getOutputStream().flush();
byteArrayOutputStream.close();
} catch (Exception e) {
e.printStackTrace();
log.error(e.getMessage());
}
}
/***
* 為PDF頁繪畫水印
* @param pdfPage PDF頁對象
* @param msg 水印信息
* @param interval 水印間隔
* @throws IOException 這里的異常是無法獲取字體異常
*/
public static void setPageWatermark(PdfPage pdfPage,PdfDocument pdfDoc, String msg, int interval) throws IOException {
// 通過PDF頁來構(gòu)建畫布
PdfCanvas pdfCanvas = new PdfCanvas(pdfPage);
// 中文顯示字體
// PdfFont font = PdfFontFactory.createFont("STSong-Light", "UniGB-UCS2-H");
float width = pdfPage.getPageSize().getWidth();
float height = pdfPage.getPageSize().getHeight();
// 開始繪畫水印
for (int x = 0; x < pdfPage.getPageSize().getWidth(); x += interval) {
for (int y = 0; y < pdfPage.getPageSize().getHeight(); y += interval) {
Canvas canvas = new Canvas(pdfCanvas, pdfDoc, new Rectangle(0, 0, width, height))
// 顏色和透明度
.setFontColor(ColorConstants.GRAY, .2f)
// 文字樣式
// .setFont(font)
// 字體大小(具體可以改)
.setFontSize(20)
.showTextAligned(msg, x, y, TextAlignment.CENTER,
VerticalAlignment.MIDDLE, 19.5f);
canvas.close();
}
}
// 釋放畫布。使用完畫布后,請使用此方法。
pdfCanvas.release();
}
/**
* 將圖片進行裁剪
*
* @param originalImage
* @param maxHeight
* @return
*/
public static ArrayList<BufferedImage> cropImageByMaxHeight(BufferedImage originalImage, int maxHeight) {
ArrayList<BufferedImage> croppedImages = new ArrayList<>();
int originalHeight = originalImage.getHeight();
int numImages = originalHeight / maxHeight;
int remainder = originalHeight % maxHeight;
for (int i = 0; i < numImages; i++) {
int y = i * maxHeight;
BufferedImage croppedImage = originalImage.getSubimage(0, y, originalImage.getWidth(), maxHeight);
croppedImages.add(croppedImage);
}
// 處理剩余高度(如有)
if (remainder > 0) {
int y = numImages * maxHeight;
BufferedImage croppedImage = originalImage.getSubimage(0, y, originalImage.getWidth(), remainder);
croppedImages.add(croppedImage);
}
return croppedImages;
}成果


以上就是Java根據(jù)前端傳回的圖片生成pdf并且加密碼和水印的詳細內(nèi)容,更多關(guān)于Java圖片生成pdf的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
基于Spring AMQP實現(xiàn)消息隊列的示例代碼
Spring AMQP作為Spring框架的一部分,是一套用于支持高級消息隊列協(xié)議(AMQP)的工具,AMQP是一種強大的消息協(xié)議,旨在支持可靠的消息傳遞,本文給大家介紹了如何基于Spring AMQP實現(xiàn)消息隊列,需要的朋友可以參考下2024-03-03
SpringBootAdmin+actuator實現(xiàn)服務(wù)監(jiān)控
這篇文章主要為大家詳細介紹了SpringBootAdmin+actuator實現(xiàn)服務(wù)監(jiān)控,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-01-01
SpringBoot集成Knife4j實現(xiàn)接口文檔和參數(shù)校驗
Knife4j 是國人開發(fā)的接口文檔增強工具,底層基于 OpenAPI 規(guī)范,但提供了比原生 Swagger UI 更美觀、更貼合國內(nèi)開發(fā)者習慣的中文界面,本文就給大家介紹了SpringBoot集成Knife4j實現(xiàn)接口文檔和參數(shù)校操作步驟,需要的朋友可以參考下2026-03-03

