Java로 PDF 파일 생성

1. 소개

이 빠른 기사에서는 인기있는 iText 및 PdfBox 라이브러리를 기반으로 처음부터 PDF 문서를 만드는 데 중점을 둡니다.

2. Maven 종속성

프로젝트에 포함되어야하는 Maven 종속성을 살펴 보겠습니다.

 com.itextpdf itextpdf 5.5.10   org.apache.pdfbox pdfbox 2.0.4 

최신 버전의 라이브러리는 iText 및 PdfBox에서 찾을 수 있습니다.

파일을 암호화해야 할 경우를 대비하여 추가하려면 하나의 추가 종속성이 필요합니다. Bounty Castle Provider 패키지에는 암호화 알고리즘 구현이 포함되어 있으며 두 라이브러리 모두에 필요합니다.

 org.bouncycastle bcprov-jdk15on 1.56  

최신 버전의 라이브러리는 Bounty Castle Provider에서 찾을 수 있습니다.

3. 개요

iText와 PdfBox는 모두 pdf 파일의 생성 / 조작에 사용되는 자바 라이브러리입니다. 라이브러리의 최종 출력은 동일하지만 약간 다른 방식으로 작동합니다. 그들을 살펴 보자.

4. IText에서 PDF 생성

4.1. PDF에 텍스트 삽입

"Hello World"텍스트가있는 새 파일이 pdf 파일에 삽입되는 방식을 살펴 보겠습니다.

Document document = new Document(); PdfWriter.getInstance(document, new FileOutputStream("iTextHelloWorld.pdf")); document.open(); Font font = FontFactory.getFont(FontFactory.COURIER, 16, BaseColor.BLACK); Chunk chunk = new Chunk("Hello World", font); document.add(chunk); document.close();

iText 라이브러리를 사용하여 pdf를 만드는 것은 Document의 Elements 인터페이스를 구현하는 객체 조작을 기반으로합니다 (버전 5.5.10에는 45 개의 구현이 있습니다).

문서에 추가하여 사용할 수있는 가장 작은 요소는 Chunk 라고하며 기본적으로 글꼴이 적용된 문자열입니다.

또한 ChunkParagraphs , Section 등과 같은 다른 요소와 결합하여 멋진 문서를 만들 수 있습니다.

4.2. 이미지 삽입

iText 라이브러리는 문서에 이미지를 추가하는 쉬운 방법을 제공합니다. Image 인스턴스 를 생성 하여 Document에 추가하기 만하면 됩니다.

Path path = Paths.get(ClassLoader.getSystemResource("Java_logo.png").toURI()); Document document = new Document(); PdfWriter.getInstance(document, new FileOutputStream("iTextImageExample.pdf")); document.open(); Image img = Image.getInstance(path.toAbsolutePath().toString()); document.add(img); document.close();

4.3. 표 삽입

pdf에 표를 추가하려고 할 때 문제가 발생할 수 있습니다. 운 좋게도 iText는 이러한 기능을 즉시 제공합니다.

먼저해야 할 일은 PdfTable 개체 를 만들고 생성자에서 테이블에 대한 여러 열을 제공하는 것입니다. 이제 다음을 호출하여 새 셀을 추가 할 수 있습니다.

이제 새로 생성 된 테이블 객체 에서 addCell 메소드를 호출하여 간단히 새 셀을 추가 할 수 있습니다 . iText는 필요한 모든 셀이 정의되어있는 한 표 행을 생성합니다. 즉, 3 개의 열이있는 표를 만들고 여기에 8 개의 셀을 추가하면 각각에 3 개의 셀이있는 2 개의 행만 표시됩니다.

예를 살펴 보겠습니다.

Document document = new Document(); PdfWriter.getInstance(document, new FileOutputStream("iTextTable.pdf")); document.open(); PdfPTable table = new PdfPTable(3); addTableHeader(table); addRows(table); addCustomRows(table); document.add(table); document.close();

3 개의 열과 3 개의 행이있는 새 테이블을 만듭니다. 첫 번째 행은 배경색과 테두리 너비가 변경된 테이블 헤더로 취급됩니다.

private void addTableHeader(PdfPTable table) { Stream.of("column header 1", "column header 2", "column header 3") .forEach(columnTitle -> { PdfPCell header = new PdfPCell(); header.setBackgroundColor(BaseColor.LIGHT_GRAY); header.setBorderWidth(2); header.setPhrase(new Phrase(columnTitle)); table.addCell(header); }); }

두 번째 행은 추가 서식없이 텍스트 만있는 세 개의 셀로 구성됩니다.

private void addRows(PdfPTable table) { table.addCell("row 1, col 1"); table.addCell("row 1, col 2"); table.addCell("row 1, col 3"); }

셀에 텍스트뿐만 아니라 이미지도 포함 할 수 있습니다. 또한 각 셀은 개별적으로 서식이 지정 될 수 있습니다. 아래에 제시된 예에서는 수평 및 수직 정렬 조정을 적용합니다.

private void addCustomRows(PdfPTable table) throws URISyntaxException, BadElementException, IOException { Path path = Paths.get(ClassLoader.getSystemResource("Java_logo.png").toURI()); Image img = Image.getInstance(path.toAbsolutePath().toString()); img.scalePercent(10); PdfPCell imageCell = new PdfPCell(img); table.addCell(imageCell); PdfPCell horizontalAlignCell = new PdfPCell(new Phrase("row 2, col 2")); horizontalAlignCell.setHorizontalAlignment(Element.ALIGN_CENTER); table.addCell(horizontalAlignCell); PdfPCell verticalAlignCell = new PdfPCell(new Phrase("row 2, col 3")); verticalAlignCell.setVerticalAlignment(Element.ALIGN_BOTTOM); table.addCell(verticalAlignCell); }

4.4. 파일 암호화

iText 라이브러리를 사용하여 권한을 적용하려면 이미 pdf 문서를 생성해야합니다. 이 예에서는 이전에 생성 된 iTextHelloWorld.pdf 파일 을 사용합니다 .

PdfReader를 사용하여 파일을로드 한 후에는 메타 데이터, 암호화 등과 같은 파일에 추가 콘텐츠를 적용하는 데 사용되는 PdfStamper 를 만들어야합니다 .

PdfReader pdfReader = new PdfReader("HelloWorld.pdf"); PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileOutputStream("encryptedPdf.pdf")); pdfStamper.setEncryption( "userpass".getBytes(), ".getBytes(), 0, PdfWriter.ENCRYPTION_AES_256 ); pdfStamper.close();

이 예에서는 두 개의 암호로 파일을 암호화했습니다. 사용자가 인쇄 할 수없는 읽기 전용 권한 만있는 사용자 암호 ( "userpass")와 pdf에 대한 전체 액세스 권한을 부여하는 마스터 키로 사용되는 소유자 암호 ( "ownerpass").

사용자가 pdf를 인쇄하도록 허용하려면 0 ( setEncryption의 세 번째 매개 변수) 대신 다음을 전달할 수 있습니다.

PdfWriter.ALLOW_PRINTING

물론 다음과 같은 다양한 권한을 혼합 할 수 있습니다.

PdfWriter.ALLOW_PRINTING | PdfWriter.ALLOW_COPY

iText를 사용하여 액세스 권한을 설정하는 동시에 삭제해야하는 임시 pdf도 생성하고 있습니다. 그렇지 않은 경우 누구든지 완전히 액세스 할 수 있습니다.

5. PdfBox에서 PDF 생성

5.1. PDF에 텍스트 삽입

iText 와 반대로 PdfBox 라이브러리는 스트림 조작을 기반으로하는 API를 제공합니다. Chunk / Paragraph 등과 같은 클래스는 없습니다 . PDDocument 클래스는 사용자가 PDPageContentStream 클래스 를 조작하여 데이터를 쓰는 메모리 내 Pdf 표현 입니다.

코드 예제를 살펴 보겠습니다.

PDDocument document = new PDDocument(); PDPage page = new PDPage(); document.addPage(page); PDPageContentStream contentStream = new PDPageContentStream(document, page); contentStream.setFont(PDType1Font.COURIER, 12); contentStream.beginText(); contentStream.showText("Hello World"); contentStream.endText(); contentStream.close(); document.save("pdfBoxHelloWorld.pdf"); document.close();

5.2. 이미지 삽입

이미지 삽입은 간단합니다.

First we need to load a file and create a PDImageXObject, subsequently draw it on the document (need to provide exact x,y coordinates).

That's all:

PDDocument document = new PDDocument(); PDPage page = new PDPage(); document.addPage(page); Path path = Paths.get(ClassLoader.getSystemResource("Java_logo.png").toURI()); PDPageContentStream contentStream = new PDPageContentStream(document, page); PDImageXObject image = PDImageXObject.createFromFile(path.toAbsolutePath().toString(), document); contentStream.drawImage(image, 0, 0); contentStream.close(); document.save("pdfBoxImage.pdf"); document.close(); 

5.3. Inserting a Table

Unfortunately, PdfBox does not provide any out-of-box methods allowing creating tables. What we can do in such situation is to draw it manually – literally, draw each line until our drawing resembles our dreamed table.

5.4. File Encryption

PdfBox library provides a possibility to encrypt, and adjust file permission for the user. Comparing to iText, it does not require to use an already existing file, as we simply use PDDocument. Pdf file permissions are handled by AccessPermission class, where we can set if a user will be able to modify, extract content or print a file.

Subsequently, we create a StandardProtectionPolicy object which adds password-based protection to the document. We can specify two types of password. The user password, after which person will be able to open a file with applied access permissions and owner password (no limitations to the file):

PDDocument document = new PDDocument(); PDPage page = new PDPage(); document.addPage(page); AccessPermission accessPermission = new AccessPermission(); accessPermission.setCanPrint(false); accessPermission.setCanModify(false); StandardProtectionPolicy standardProtectionPolicy = new StandardProtectionPolicy("ownerpass", "userpass", accessPermission); document.protect(standardProtectionPolicy); document.save("pdfBoxEncryption.pdf"); document.close(); 

이 예에서는 사용자가 사용자 암호를 제공하면 파일을 수정하고 인쇄 할 수없는 상황을 보여줍니다.

6. 결론

이 튜토리얼에서는 두 가지 인기있는 Java 라이브러리에서 pdf 파일을 만드는 방법에 대해 설명했습니다.

전체 예제는 GitHub의 Maven 기반 프로젝트에서 찾을 수 있습니다.