PDF 문서 모음을 JAVA에서 하나의 큰 PDF 문서로 병합(서버측)하는 가장 쉬운 방법은 무엇입니까?
-
01-07-2019 - |
문제
우리가 사용하는 레거시 라이브러리에 의해 즉시 생성되어 디스크에 기록되는 3개의 PDF 문서가 있습니다.내 JAVA 서버 코드가 이 3개의 문서를 가져와 문서 #1의 모든 페이지와 문서 #2의 모든 페이지 등으로 구성된 하나의 긴 PDF 문서로 변환하는 가장 쉬운 방법은 무엇입니까?
이상적으로는 이것이 메모리에서 발생하여 클라이언트에 스트림으로 반환할 수 있기를 원하지만 디스크에 쓰는 것도 옵션입니다.
해결책
@J D OConal, 팁을 주셔서 감사합니다. 보내주신 기사는 매우 오래된 것이었지만 iText를 추천해 주었습니다.필요한 작업을 정확히 수행하는 방법을 설명하는 이 페이지를 찾았습니다.http://java-x.blogspot.com/2006/11/merge-pdf-files-with-itext.html
다른 답변을 주셔서 감사합니다. 하지만 피할 수 있다면 다른 프로세스를 생성하고 싶지 않으며 프로젝트에 이미 itext.jar이 있으므로 외부 종속성을 추가하지 않습니다.
내가 작성한 코드는 다음과 같습니다.
public class PdfMergeHelper {
/**
* Merges the passed in PDFs, in the order that they are listed in the java.util.List.
* Writes the resulting PDF out to the OutputStream provided.
*
* Sample Usage:
* List<InputStream> pdfs = new ArrayList<InputStream>();
* pdfs.add(new FileInputStream("/location/of/pdf/OQS_FRSv1.5.pdf"));
* pdfs.add(new FileInputStream("/location/of/pdf/PPFP-Contract_Genericv0.5.pdf"));
* pdfs.add(new FileInputStream("/location/of/pdf/PPFP-Quotev0.6.pdf"));
* FileOutputStream output = new FileOutputStream("/location/to/write/to/merge.pdf");
* PdfMergeHelper.concatPDFs(pdfs, output, true);
*
* @param streamOfPDFFiles the list of files to merge, in the order that they should be merged
* @param outputStream the output stream to write the merged PDF to
* @param paginate true if you want page numbers to appear at the bottom of each page, false otherwise
*/
public static void concatPDFs(List<InputStream> streamOfPDFFiles, OutputStream outputStream, boolean paginate) {
Document document = new Document();
try {
List<InputStream> pdfs = streamOfPDFFiles;
List<PdfReader> readers = new ArrayList<PdfReader>();
int totalPages = 0;
Iterator<InputStream> iteratorPDFs = pdfs.iterator();
// Create Readers for the pdfs.
while (iteratorPDFs.hasNext()) {
InputStream pdf = iteratorPDFs.next();
PdfReader pdfReader = new PdfReader(pdf);
readers.add(pdfReader);
totalPages += pdfReader.getNumberOfPages();
}
// Create a writer for the outputstream
PdfWriter writer = PdfWriter.getInstance(document, outputStream);
document.open();
BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
PdfContentByte cb = writer.getDirectContent(); // Holds the PDF
// data
PdfImportedPage page;
int currentPageNumber = 0;
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();
pageOfCurrentReaderPDF++;
currentPageNumber++;
page = writer.getImportedPage(pdfReader, pageOfCurrentReaderPDF);
cb.addTemplate(page, 0, 0);
// Code for pagination.
if (paginate) {
cb.beginText();
cb.setFontAndSize(bf, 9);
cb.showTextAligned(PdfContentByte.ALIGN_CENTER, "" + currentPageNumber + " of " + totalPages,
520, 5, 0);
cb.endText();
}
}
pageOfCurrentReaderPDF = 0;
}
outputStream.flush();
document.close();
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (document.isOpen()) {
document.close();
}
try {
if (outputStream != null) {
outputStream.close();
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
}
다른 팁
나는 사용했다 pdftk 큰 효과를 발휘합니다.이는 Java 앱에서 실행해야 하는 외부 애플리케이션입니다.
iText는 변경된 것으로 보이며 이제는 그다지 좋은 도움이 되지 않는 상업용 라이센스 요구 사항도 있습니다(문서를 원하십니까?우리 책을 구입하세요!).
결국 PDFSharp를 찾았습니다. http://www.pdfsharp.net/ 그리고 그걸 사용해서.여러 PDF 문서를 연결하는 샘플은 간단하고 따라하기 쉽습니다. http://www.pdfsharp.net/wiki/ConcatenateDocuments-sample.ashx
무작위를 즐기십시오
이것 좀 보세요 Java 오픈 소스 PDF 라이브러리 목록.
또한 확인해보세요 이 기사.
[편집하다:사용하기 쉬운 Ghostscript가 항상 있지만, 누가 더 많은 의존성을 원하는가?]
PDF박스 이 작업을 수행하는 가장 쉬운 방법은 코드 내에 PDFMerger라는 유틸리티가 있어 작업을 매우 쉽게 만들어줍니다. for 루프와 두 줄의 코드만 있으면 모두 완료되었습니다. :)