Java操作pdf文件的方法大全
一、判斷一個(gè)文件是否是pdf文件
pdf文件頭部位置,包含著PDF版本信息,可以通過(guò)這個(gè)來(lái)判斷:
@PostMapping(value = "/upload") public void uploadFile(@RequestParam MultipartFile file) { InputStream inputStream = null; try { inputStream = file.getInputStream(); if (file.getOriginalFilename().endsWith("pdf") || file.getOriginalFilename().endsWith("PDF")) { // pdf檢查 if (!checkPdfType(inputStream)) { logger.info("pdf文件檢查失敗"); return result.failed().template(StandardI18nTemplate.MSG_Error).arguments("請(qǐng)上傳合法的pdf文件"); } // 流重置 inputStream.reset(); } } catch (Exception e) { logger.error("上傳失敗", e); } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { logger.error("關(guān)閉inputStream失敗", e); } } } } // 讀取前幾個(gè)字符,判斷有沒(méi)有PDF關(guān)鍵字 public boolean checkPdfType(InputStream inputStream) { try { byte[] bytes = new byte[20]; inputStream.read(bytes); String string = new String(bytes); if (!string.contains("PDF")) { return false; } } catch (Exception e) { logger.error("checkPdfType error", e); return false; } return true; }
二、多個(gè)pdf文件合并為一個(gè)
1、需要的包
<dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <version>5.5.13.3</version> </dependency>
2、實(shí)現(xiàn)
import com.itextpdf.text.*; import com.itextpdf.text.pdf.*; public static void main(String[] args) { List<String> pdfs = new ArrayList<>(); pdfs.add("E:\\test.pdf"); pdfs.add("E:\\test2.pdf"); mergePdf(pdfs, "E:\\merge.pdf"); } /** * 將多個(gè)pdf合并成一個(gè)pdf文件 */ public static void mergePdf(List<String> pdfs, String mergeFilePath) { List<PdfReader> readers = new ArrayList<>(); try { // 創(chuàng)建一個(gè)新的文檔 Document document = new Document(); // 創(chuàng)建一個(gè)PDF復(fù)制對(duì)象 PdfCopy copy = new PdfCopy(document, new FileOutputStream(mergeFilePath)); // 打開(kāi)文檔 document.open(); // 讀取需要合并的PDF文件 for (String file : pdfs) { readers.add(new PdfReader(file)); } for (PdfReader reader : readers) { // 將讀取的PDF文件合并到新的文檔中 copy.addDocument(reader); } // 關(guān)閉文檔 document.close(); logger.info("PDF合并完成!"); } catch (Exception e) { logger.error("PDF合并失?。?, e); } finally { for (PdfReader reader : readers) { if (reader != null) { reader.close(); } } } }
三、使用itextpdf5手繪pdf
1、需要的包
<dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <version>5.5.13.3</version> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>itext-asian</artifactId> <version>5.2.0</version> </dependency>
官網(wǎng):https://kb.itextpdf.com/home/it7kb/ebooks
2、代碼
import com.itextpdf.text.*; import com.itextpdf.text.pdf.BaseFont; import com.itextpdf.text.pdf.PdfPCell; import java.io.IOException; public class PdfHelper { // 宋體 漢字支持 public static BaseFont STSongLight; static { try { STSongLight = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); } catch (DocumentException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * 漢字支持,宋體支持 */ public static BaseFont getSTSongLightBaseFont() { return STSongLight; } public static PdfPCell getCell(String text, int colspan, int rowspan) { Font font = new Font(STSongLight, 16); Chunk chunk = new Chunk(text, font); Paragraph paragraph = new Paragraph(chunk); PdfPCell cell = new PdfPCell(paragraph); cell.setHorizontalAlignment(Element.ALIGN_CENTER); cell.setColspan(colspan); cell.setRowspan(rowspan); return cell; } }
import com.itextpdf.text.*; import com.itextpdf.text.pdf.PdfPCell; import com.itextpdf.text.pdf.PdfPTable; import com.itextpdf.text.pdf.PdfWriter; import java.io.FileOutputStream; import java.io.IOException; public class PdfTest { public static void main(String[] args) throws IOException, DocumentException { // 定義pdf大小為A4紙大小,并且上下左右邊距都為50 Document document = new Document(PageSize.A4, 50, 50, 50, 50); PdfWriter.getInstance(document, new FileOutputStream("G:\\test.pdf")); document.open(); // 1、輸出一個(gè)段落 document.add(new Paragraph("Hello World!")); // 2、添加空行 document.add(Chunk.NEWLINE); // 3、添加列表 // 字體可以設(shè)置 大小,加粗/傾斜下劃線(xiàn)等,顏色 ,可以通過(guò)構(gòu)造方法一行生成,也可以調(diào)用set方法 Font font3 = new Font(PdfHelper.getSTSongLightBaseFont(), 18f, Font.BOLD, new BaseColor(0, 0, 255)); // 文本 加上這個(gè)才會(huì)顯示中文?。? Chunk chunk = new Chunk("列表輸出:", font3); // 段落 Paragraph paragraph3 = new Paragraph(chunk); paragraph3.setFont(font3);// 字體 paragraph3.setPaddingTop(10); paragraph3.setAlignment(Element.ALIGN_CENTER); // 居中 document.add(paragraph3); // Create a List List list3 = new List(); list3.setSymbolIndent(12); list3.setListSymbol("\u2022"); // 列表符號(hào) // Add ListItem objects 可以設(shè)置字體等 ListItem listItem3 = new ListItem("Never gonna give you up"); listItem3.setFont(font3); list3.add(listItem3); list3.add(new ListItem("Never gonna let you down")); list3.add(new ListItem("Never gonna run around and desert you")); list3.add(new ListItem("Never gonna make you cry")); list3.add(new ListItem("Never gonna say goodbye")); list3.add(new ListItem("Never gonna tell a lie and hurt you")); // Add the list document.add(list3); document.add(Chunk.NEWLINE); // 4.添加圖片 // 段落 Paragraph paragraph4 = new Paragraph(); paragraph4.add(new Chunk("我是java搬運(yùn)工,我會(huì)", new Font(PdfHelper.getSTSongLightBaseFont(), 18f))); Image image4_1 = Image.getInstance("G:\\docker.png"); // 也可以傳遞網(wǎng)絡(luò)圖片 // image4_1.setAlignment(Element.ALIGN_CENTER); image4_1.scaleToFit(50, 50); // 寬高限制 paragraph4.add(image4_1); paragraph4.add(new Chunk("我還會(huì)", new Font(PdfHelper.getSTSongLightBaseFont(), 18f))); Image image4_2 = Image.getInstance("G:\\mybatis.jpg"); // 也可以傳遞網(wǎng)絡(luò)圖片 // image4_2.setAlignment(Element.ALIGN_CENTER); image4_2.scaleToFit(50, 50); // 寬高限制 paragraph4.add(image4_2); document.add(paragraph4); document.add(Chunk.NEWLINE); // 5.表格 // 7列的表格 PdfPTable table5 = new PdfPTable(7); // 每一列表格的寬度比例 float[] columnWidths = {3, 3, 2, 3, 2, 4, 3}; table5.setWidths(columnWidths); table5.setWidthPercentage(95);// 表格占頁(yè)面的比例 PdfPCell defaultCell5 = table5.getDefaultCell(); defaultCell5.setBorder(1); // 邊框 defaultCell5.setPadding(2); table5.addCell(PdfHelper.getCell("姓名", 1, 1)); table5.addCell(PdfHelper.getCell("張三", 1, 1)); table5.addCell(PdfHelper.getCell("性別", 1, 1)); table5.addCell(PdfHelper.getCell("男", 1, 1)); table5.addCell(PdfHelper.getCell("年齡", 1, 1)); table5.addCell(PdfHelper.getCell("18", 1, 1)); Image img = Image.getInstance("G:\\docker.png"); img.scaleToFit(83, 168); PdfPCell imageCell = new PdfPCell(img); imageCell.setBorderWidth(0); imageCell.setHorizontalAlignment(Element.ALIGN_LEFT); // 設(shè)置單元格內(nèi)容水平對(duì)齊方式 imageCell.setColspan(1); imageCell.setRowspan(3); imageCell.setPadding(2); table5.addCell(imageCell); document.add(table5); // 關(guān)閉文檔 document.close(); } }
4、效果
四、根據(jù)pdf模板導(dǎo)出pdf
1、引包
<dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <version>5.5.13.3</version> </dependency>
2、準(zhǔn)備pdf模板
(1)我們使用wps打開(kāi)原始PDF 注意,wps編輯表單需要會(huì)員,可以使用其他軟件(Adobe Acrobat Pro或者福昕等)
(2)編輯表單
最終的結(jié)果:雙擊黑框可以編輯文字格式:
3、編碼
import com.itextpdf.text.*; import com.itextpdf.text.pdf.*; import java.io.ByteArrayOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.HashMap; import java.util.Map; /** * Created by cxf on 2019/11/12. * https://www.cnblogs.com/wangpeng00700/p/8418594.html * 用Adobe Acrobat Pro創(chuàng)建表單 */ public class ItextPdfUtils { // 利用模板生成pdf public static void pdfout(Map<String,Object> o) { // 模板路徑 String templatePath = "E:\\mytest.pdf"; // 生成的新文件路徑 String newPDFPath = "E:\\testout1.pdf"; PdfReader reader; FileOutputStream out; ByteArrayOutputStream bos; PdfStamper stamper; try { BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); Font FontChinese = new Font(bf, 5, Font.NORMAL); out = new FileOutputStream(newPDFPath);// 輸出流 reader = new PdfReader(templatePath);// 讀取pdf模板 bos = new ByteArrayOutputStream(); stamper = new PdfStamper(reader, bos); AcroFields form = stamper.getAcroFields(); //文字類(lèi)的內(nèi)容處理 Map<String,String> datemap = (Map<String,String>)o.get("datemap"); form.addSubstitutionFont(bf); for(String key : datemap.keySet()){ String value = datemap.get(key); form.setField(key,value); } //圖片類(lèi)的內(nèi)容處理 Map<String,String> imgmap = (Map<String,String>)o.get("imgmap"); for(String key : imgmap.keySet()) { String value = imgmap.get(key); String imgpath = value; int pageNo = form.getFieldPositions(key).get(0).page; Rectangle signRect = form.getFieldPositions(key).get(0).position; float x = signRect.getLeft(); float y = signRect.getBottom(); //根據(jù)路徑讀取圖片 Image image = Image.getInstance(imgpath); //獲取圖片頁(yè)面 PdfContentByte under = stamper.getOverContent(pageNo); //圖片大小自適應(yīng) image.scaleToFit(signRect.getWidth(), signRect.getHeight()); //添加圖片 image.setAbsolutePosition(x, y); under.addImage(image); } stamper.setFormFlattening(true);// 如果為false,生成的PDF文件可以編輯,如果為true,生成的PDF文件不可以編輯 stamper.close(); Document doc = new Document(); Font font = new Font(bf, 32); PdfCopy copy = new PdfCopy(doc, out); doc.open(); PdfImportedPage importPage = copy.getImportedPage(new PdfReader(bos.toByteArray()), 1); copy.addPage(importPage); doc.close(); } catch (IOException e) { System.out.println(e); } catch (DocumentException e) { System.out.println(e); } } public static void main(String[] args) { Map<String,String> map = new HashMap(); map.put("name","張三"); map.put("age","永遠(yuǎn)18"); map.put("weather","晴朗"); Map<String,String> map2 = new HashMap(); map2.put("img","E:\\mybatis.jpg"); Map<String,Object> o=new HashMap(); o.put("datemap",map); o.put("imgmap",map2); pdfout(o); } }
以上就是Java操作pdf文件的方法大全的詳細(xì)內(nèi)容,更多關(guān)于Java操作pdf的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
非常適合新手學(xué)生的Java線(xiàn)程池超詳細(xì)分析
作者是一個(gè)來(lái)自河源的大三在校生,以下筆記都是作者自學(xué)之路的一些淺薄經(jīng)驗(yàn),如有錯(cuò)誤請(qǐng)指正,將來(lái)會(huì)不斷的完善筆記,幫助更多的Java愛(ài)好者入門(mén)2022-03-03詳解SpringBoot注冊(cè)Windows服務(wù)和啟動(dòng)報(bào)錯(cuò)的原因
這篇文章主要介紹了詳解SpringBoot注冊(cè)Windows服務(wù)和啟動(dòng)報(bào)錯(cuò)的原因,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-03-03Java訪(fǎng)問(wèn)修飾符public、private、protected及默認(rèn)訪(fǎng)問(wèn)權(quán)限詳解
這篇文章主要介紹了Java訪(fǎng)問(wèn)修飾符public、private、protected及默認(rèn)訪(fǎng)問(wèn)權(quán)限的相關(guān)資料,每種修飾符都有其特定的使用場(chǎng)景,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-01-01Spring和activiti進(jìn)行整合過(guò)程解析
這篇文章主要介紹了Spring和activiti進(jìn)行整合過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03tio-http-server打包為二進(jìn)制文件的實(shí)現(xiàn)及優(yōu)勢(shì)詳解
這篇文章主要為大家介紹了tio-http-server打包為二進(jìn)制文件實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12在Map中實(shí)現(xiàn)key唯一不重復(fù)操作
這篇文章主要介紹了在Map中實(shí)現(xiàn)key唯一不重復(fù)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08Java 關(guān)于eclipse導(dǎo)入項(xiàng)目發(fā)生的問(wèn)題及解決方法(推薦)
下面小編就為大家分享一篇Java 關(guān)于eclipse導(dǎo)入項(xiàng)目發(fā)生的問(wèn)題及解決方法(推薦),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2017-12-12