溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何使用itextpdf解決PDF合并的問題

發(fā)布時間:2021-07-07 09:47:20 來源:億速云 閱讀:241 作者:小新 欄目:開發(fā)技術(shù)

這篇文章主要介紹了如何使用itextpdf解決PDF合并的問題,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

itextpdf解決PDF合并的問題

本文章是我在項目開發(fā)過程中解決了一個關(guān)于PDF顯示的需求而記錄的。

需求是這樣的,需要將兩個PDF進行合并,一個PDF是根據(jù)數(shù)據(jù)庫的信息在在后臺形成的(實際不存在的PDF),另一個是磁盤保存的PDF文件(這個PDF文件后期會變成從云端獲?。?/p>

作為一個Java菜鳥,這個問題解決了數(shù)天,還是在leader的指導下解決的。在這里做一下關(guān)鍵代碼的記錄。

項目主要包含了以下關(guān)鍵詞:(我不做詳解了,主要是用了這些)

- Spring MVC、Spring、Hibernate

- Maven

- Java

- itextpdf

- MySQL

- JavaWeb相關(guān)

首先是itextpdf的依賴

<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itextpdf</artifactId>
    <version>5.5.10</version>
</dependency>

如何在后臺生成一個PDF

這個問題,百度上有很多解決方案,因為我需要將這個生成的PDF和已存在的PDF拼接,于是嘗試了多種方案,決定將這個以文檔的形式,將這個文檔轉(zhuǎn)為字節(jié)數(shù)組,然后用itextpdf將流讀取到PDF中。

生成PDF的部分代碼:

import java.io.ByteArrayOutputStream;
import com.model.User;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.parser.PdfReaderContentParser;
public class ReportKit {
     public static byte[] createReport(User user) throws Exception {
               ByteArrayOutputStream ba = new ByteArrayOutputStream();
               Document doc = new Document();//創(chuàng)建一個document對象
               PdfWriter writer = PdfWriter.getInstance(doc, ba);//這個PdfWriter會一直往文檔里寫內(nèi)容。
              doc.open();//開啟文檔
              BaseFont bfChinese = BaseFont.createFont("c://windows//fonts//msyh.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
              com.itextpdf.text.Font FontChinese18 = new com.itextpdf.text.Font(bfChinese, 18, com.itextpdf.text.Font.BOLD);
              com.itextpdf.text.Font FontChinese12 = new com.itextpdf.text.Font(bfChinese, 12, com.itextpdf.text.Font.NORMAL);
              com.itextpdf.text.Font FontChinese11 = new com.itextpdf.text.Font(bfChinese, 11, com.itextpdf.text.Font.ITALIC);
              Font fontChinese =  new  Font(bfChinese  ,  12 , Font.NORMAL, BaseColor.BLACK);
              Paragraph pf = new Paragraph("");
              //加入空行
              Paragraph blankRow1 = new Paragraph(24f," ",FontChinese18);
              doc.add(blankRow1);
              //table2
              PdfPTable table25 = new PdfPTable(2);
              //設(shè)置每列寬度比例
              int width31[] = {2,98};
              table25.setWidths(width31);
              table25.getDefaultCell().setBorder(0);
              PdfPCell cell25 = new PdfPCell(new Paragraph("這是一個報告",FontChinese18));
              cell25.setBorder(0);
              table25.addCell("");
              table25.addCell(cell25);
              doc.add(table25);
              Paragraph blankRow3 = new Paragraph(18f, "Report ", FontChinese11);
              blankRow3.setAlignment(PdfContentByte.ALIGN_RIGHT);
              doc.add(blankRow3);        
              BaseColor lightGrey = new BaseColor(0xCC,0xCC,0xCC);
              PdfPTable table8 = new PdfPTable(6);
            //設(shè)置table的寬度為100%
            table8.setWidthPercentage(100);
            //設(shè)置不同列的寬度
            float[] columnWidths = {1.6f, 1.6f, 1.6f, 1.6f, 1.6f, 1.6f};
            table8.setWidths(columnWidths);
              PdfPCell cell1 = new PdfPCell(new Paragraph("用戶名",FontChinese12));
            PdfPCell cell2 = new PdfPCell(new Paragraph("出生日期",FontChinese12));
            PdfPCell cell3 = new PdfPCell(new Paragraph("性別",FontChinese12));
            PdfPCell cell4 = new PdfPCell(new Paragraph("身高",FontChinese12));
            PdfPCell cell5 = new PdfPCell(new Paragraph("體重",FontChinese12));
            PdfPCell cell6 = new PdfPCell(new Paragraph("地區(qū)",FontChinese12));
            PdfPCell cell7 = new PdfPCell(new Paragraph(user.getAccessname(),FontChinese12));
            PdfPCell cell8 = new PdfPCell(new Paragraph(user.getBirthday(),FontChinese12));
            PdfPCell cell9 = new PdfPCell(new Paragraph(sex,FontChinese12));
            PdfPCell cell10 = new PdfPCell(new Paragraph(String.valueOf(user.getHeight()),FontChinese12));
            PdfPCell cell11 = new PdfPCell(new Paragraph(String.valueOf(user.getWeight()),FontChinese12));
            PdfPCell cell12 = new PdfPCell(new Paragraph(user.getArea_name(),FontChinese12));
            //表格高度
            cell1.setFixedHeight(30);
            cell2.setFixedHeight(30);
            cell3.setFixedHeight(30);
            cell4.setFixedHeight(30);
            cell5.setFixedHeight(30);
            cell6.setFixedHeight(30);
            cell7.setFixedHeight(30);
            cell8.setFixedHeight(30);
            cell9.setFixedHeight(30);
            cell10.setFixedHeight(30);
            cell11.setFixedHeight(30);
            cell12.setFixedHeight(30);
            //水平居中
           cell1.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell2.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell3.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell4.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell5.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell6.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell7.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell8.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell9.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell10.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell11.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell12.setHorizontalAlignment(Element.ALIGN_CENTER);
            //垂直居中
            cell1.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell2.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell3.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell4.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell5.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell6.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell7.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell8.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell9.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell10.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell11.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell12.setVerticalAlignment(Element.ALIGN_MIDDLE);
            //邊框顏色
            cell1.setBorderColor(lightGrey);
            cell2.setBorderColor(lightGrey);
            cell3.setBorderColor(lightGrey);
            cell4.setBorderColor(lightGrey);
            cell5.setBorderColor(lightGrey);
            cell6.setBorderColor(lightGrey);
            cell7.setBorderColor(lightGrey);
            cell8.setBorderColor(lightGrey);
            cell9.setBorderColor(lightGrey);
            cell10.setBorderColor(lightGrey);
            cell11.setBorderColor(lightGrey);
            cell12.setBorderColor(lightGrey);
            table8.addCell(cell1);
            table8.addCell(cell2);
            table8.addCell(cell3);
            table8.addCell(cell4);
            table8.addCell(cell5);
            table8.addCell(cell6);
            table8.addCell(cell7);
            table8.addCell(cell8);
            table8.addCell(cell9);
            table8.addCell(cell10);
            table8.addCell(cell11);
            table8.addCell(cell12);        
            doc.add(table8);
            doc.close();//(有開啟文檔,就要記得關(guān)閉文檔)
            writer.close();
            byte[] bytes = ba.toByteArray();          
            return bytes;
     }
}

用document來編輯文檔,真的蠻惡心的,費時費力,排版也不好調(diào),如果能有更加好用的方式,希望大家能告訴我。

到這里,調(diào)用這個方法,就可以獲得這個文檔的字節(jié)數(shù)組了。

接下來開始拼接PDF。因為是結(jié)合前端頁面實現(xiàn)的。因此這個方法是我在controller完成的。

//注意這里的produces,“application/pdf”,正是因為設(shè)置了這個,使得整個方法會將文檔以PDF的格式返回到頁面。
@RequestMapping(value = "/newPdf/{report_name}", produces = "application/pdf;charset=UTF-8")
    public void updateReport(Model model, @PathVariable String report_name, HttpServletRequest request,
            HttpServletResponse response,HttpSession session) {
        try {
            User user = (User) session.getAttribute("user");
            //這是用戶登錄后保存到session里的用戶信息(可以用別的對象來替代這個)
            if(user==null){
                return ;
            }
            PdfReader reader1 =null;
            try {
                // 調(diào)用剛剛寫的生成PDF的方法,將這個字節(jié)數(shù)組獲取。
                byte[] pdfUserByte=ReportKit.createReport(user);
                if(pdfUserByte==null||pdfUserByte.length==0){
                    return;
                }
                //用pdfReader來讀取字節(jié)數(shù)組,這里將文檔信息讀入
                 reader1 = new PdfReader(pdfUserByte);
            } catch (Exception e) {
                System.out.println(e.getMessage());
                return ;
            }
            if(reader1==null) return;
            //第二個PDF的讀取
            PdfReader reader2;
            // 報告的PDF
            reader2 = new PdfReader("C:\\Users\\Administrator\\Desktop\\report.pdf");
            Document document = new Document();
            PdfWriter writer = PdfWriter.getInstance(document, response.getOutputStream());
            document.open();
            PdfContentByte cb = writer.getDirectContent();
            int totalPages = 0;
            totalPages += reader1.getNumberOfPages();
            totalPages += reader2.getNumberOfPages();
            java.util.List<PdfReader> readers = new ArrayList<PdfReader>();
            readers.add(reader1);
            readers.add(reader2);
            int pageOfCurrentReaderPDF = 0;
            Iterator<PdfReader> iteratorPDFReader = readers.iterator();
            // Loop through the PDF files and add to the output.
            while (iteratorPDFReader.hasNext()) {
                PdfReader pdfReader = iteratorPDFReader.next();
                // Create a new page in the target for each source page.
                while (pageOfCurrentReaderPDF < pdfReader.getNumberOfPages()) {
                    document.newPage();//創(chuàng)建新的一頁
                    pageOfCurrentReaderPDF++;
                    PdfImportedPage page = writer.getImportedPage(pdfReader, pageOfCurrentReaderPDF);
                    cb.addTemplate(page, 0, 0);
                }
                pageOfCurrentReaderPDF = 0;
            }
            document.close();
            writer.close();
        } catch (IOException | DocumentException e) {
            e.printStackTrace();
        }
    }

關(guān)于如何在頁面預覽這個PDF,我用了object標簽來獲取。

jsp上的部分片段

<div class="pdf" id="pdf" ><!-- pdf -->
    <object type="application/pdf" data="http://localhost:8080/project/newPdf/${report.report_name}" id="review"  > 
    </object>
    </div>

標簽很好的實現(xiàn)了PDF預覽的功能,如果是URL的PDF,data直接輸入URL,就能將PDF在頁面預覽,感覺蠻好用的。

iText 合并PDF文件報錯

在使用iText操作PDF進行合并的時候報錯:

com.lowagie.text.exceptions.BadPasswordException: PdfReader not opened with owner password

public static PdfReader unlockPdf(PdfReader pdfReader) {
     if (pdfReader == null) {
      return pdfReader;
     }
     try {
      java.lang.reflect.Field f = pdfReader.getClass().getDeclaredField("encrypted");
      f.setAccessible(true);
      f.set(pdfReader, false);
     } catch (Exception e) {
       // ignore
     }
     return pdfReader;
    }

對reader使用上述方法即可解決該問題。

感謝你能夠認真閱讀完這篇文章,希望小編分享的“如何使用itextpdf解決PDF合并的問題”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,更多相關(guān)知識等著你來學習!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI