Java根據(jù)前端傳回的圖片生成pdf并且加密碼和水印
場景
當(dāng)前需求,前端通過html2canvas將頁面報(bào)表生成圖片下載,可以仍然不滿意。
需要java后端將前端傳過來的圖片生成pdf,并且加密碼加水印。
重點(diǎn)
pdf使用A4大小,但是要考慮。根據(jù)A4寬高縮放圖片后,圖片仍然大于A4長度,此時要對圖片進(jìn)行裁剪(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, // 加密標(biāo)準(zhǔn) 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) // 字體大?。ň唧w可以改) .setFontSize(20) .showTextAligned(msg, x, y, TextAlignment.CENTER, VerticalAlignment.MIDDLE, 19.5f); canvas.close(); } } // 釋放畫布。使用完畫布后,請使用此方法。 pdfCanvas.release(); } /** * 將圖片進(jìn)行裁剪 * * @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并且加密碼和水印的詳細(xì)內(nèi)容,更多關(guān)于Java圖片生成pdf的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
JAVA中關(guān)于Long類型返回前端精度丟失問題處理辦法
這篇文章主要介紹了后端JavaBean的id屬性從Long類型改為雪花算法后出現(xiàn)的精度丟失問題,解決方案包括將id字段類型改為字符串或使用Jackson序列化方式,需要的朋友可以參考下2024-11-11Spring Cloud Eureka 服務(wù)上下線監(jiān)控的實(shí)現(xiàn)
這篇文章主要介紹了Spring Cloud Eureka 服務(wù)上下線監(jiān)控的實(shí)現(xiàn),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-09-09Java中sleep()與wait()的區(qū)別總結(jié)
因?yàn)樽罱鼘W(xué)習(xí)時正好碰到這兩個方法,就查閱相關(guān)資料,并通過程序?qū)崿F(xiàn),進(jìn)行區(qū)別總結(jié)一下,所以下面這篇文章主要給大家總結(jié)介紹了關(guān)于Java中sleep()與wait()區(qū)別的相關(guān)資料,需要的朋友可以參考,下面來一起看看吧。2017-05-05java中URLencode、URLdecode及Base64加解密轉(zhuǎn)換
本文主要介紹了java中URLencode、URLdecode及Base64加解密轉(zhuǎn)換,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-01-01