JavaでPDF作成してみた。

#はじめに
帳票出力なんてどこのシステムでも見られたものですが、最近はペーパーレス化だなんだで、紙で出力すること自体減ってきているような気がしています。とはいえ帳票的なものはまだまだ必要な商習慣。簡単にPDFデータを作ってみましょう。

#ライブラリ
pdfbox-2.0.8

ダウンロードはこちらから。
[公式](https://pdfbox.apache.org/downloads.html)

##まずはファイルを作成してみる

```
package pdf;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;

public class PdfTest {

    public static void main(String args[]) {
	    try {
	    	
	        // ドキュメントオブジェクトの作成
	        PDDocument document = new PDDocument();

	        // ページオブジェクトの作成
	        PDPage page = new PDPage();
	        document.addPage(page);

	        // ドキュメントを保存します
	        document.save("test.pdf");
	        document.close();
	    }
	    catch (Exception e) {
	        e.printStackTrace();
	    }
	}
}
```

##実行結果

![image.png](https://qiita-image-store.s3.amazonaws.com/0/212960/f26ee9ef-2a66-c8ad-a099-79e8c9a45c2b.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/212960/277bb029-4637-c767-cc9c-ea3d1b82f657.png)

1ページだけのファイルが出来ましたね。

##文字を出力する
次に文字の出力です。

```
package pdf;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType1Font;

public class PdfTest {

    public static void main(String args[]) {
	    try {
	    	
	        // ドキュメントオブジェクトの作成
	        PDDocument document = new PDDocument();

	        // ページオブジェクトの作成
	        PDPage page = new PDPage();
	        document.addPage(page);

	        //文字出力処理
	        PDPageContentStream contentStream = new PDPageContentStream(document, page);
	        contentStream.beginText();
	        //フォント指定
	        PDFont font = PDType1Font.TIMES_ITALIC;
	        contentStream.setFont(font, 12);
	        //出力位置指定
	        contentStream.newLineAtOffset(0f, 0f);
	        //出力文字列
	        contentStream.showText( "HelloWorld" );
	        contentStream.endText();
	        contentStream.close();
	        
	        // ドキュメントを保存します
	        document.save("test2.pdf");
	        document.close();
	    }
	    catch (Exception e) {
	        e.printStackTrace();
	    }
	}
}
```

##実行結果
![image.png](https://qiita-image-store.s3.amazonaws.com/0/212960/cbdaeae3-876c-8b31-d43e-a80cedacbf10.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/212960/ae2185cc-e82f-5956-74a9-b32973b24c94.png)

出力位置をcontentStream.newLineAtOffset(0f, 0f)としていますので、一番左下に出力されます。出力フォントも色々種類がありますよ。

##日本語を出力する

```
package pdf;

import java.io.File;

import org.apache.fontbox.ttf.TrueTypeCollection;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType0Font;

public class PdfTest {

    public static void main(String args[]) {
	    try {
	    	
	        // ドキュメントオブジェクトの作成
	        PDDocument document = new PDDocument();

	        // ページオブジェクトの作成
	        PDPage page = new PDPage();
	        document.addPage(page);

	        //文字出力処理
	        PDPageContentStream contentStream = new PDPageContentStream(document, page);
	        contentStream.beginText();
	        //フォント指定
	        File file = new File("C:/Windows/Fonts/msmincho.ttc");
	        TrueTypeCollection collection = new TrueTypeCollection(file);
	        PDFont font = PDType0Font.load(document, collection.getFontByName("MS-Mincho"), true);

	        contentStream.setFont(font, 12);
	        //出力位置指定
	        contentStream.newLineAtOffset(0f, 755f);
	        //出力文字列
	        contentStream.showText( "こんにちは世界" );
	        contentStream.endText();
	        contentStream.close();
	        
	        // ドキュメントを保存します
	        document.save("test3.pdf");
	        document.close();
	    }
	    catch (Exception e) {
	        e.printStackTrace();
	    }
	}
}
```

##実行結果
![image.png](https://qiita-image-store.s3.amazonaws.com/0/212960/a5498aed-121d-77d1-703b-aae4695e04b1.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/212960/5b610235-50cd-4868-eec5-b195126c208b.png)

フォントファイルは.ttfと.ttcで若干扱いが変わってきます。今回は.ttcを使用しています。

##ファイルを作成せず、PDFデータのみ保持する
業務のケースによっては実ファイルを作成せず、データのみ保存しておきたい、というような要件があるかもしれません。特に問題なく実現できます。

```
package pdf;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.apache.fontbox.ttf.TrueTypeCollection;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.common.PDStream;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType0Font;

public class PdfTest {

    public static void main(String args[]) {
	    try {
	    	
	        // ドキュメントオブジェクトの作成
	        PDDocument document = new PDDocument();

	        // ページオブジェクトの作成
	        PDPage page = new PDPage();
	        document.addPage(page);

	        //文字出力処理
	        PDPageContentStream contentStream = new PDPageContentStream(document, page);
	        contentStream.beginText();
	        //フォント指定
	        File file = new File("C:/Windows/Fonts/msmincho.ttc");
	        TrueTypeCollection collection = new TrueTypeCollection(file);
	        PDFont font = PDType0Font.load(document, collection.getFontByName("MS-Mincho"), true);

	        contentStream.setFont(font, 12);
	        //出力位置指定
	        contentStream.newLineAtOffset(0f, 755f);
	        //出力文字列
	        contentStream.showText( "こんにちは世界。データのみ保存。" );
	        contentStream.endText();
	        contentStream.close();

	        // ドキュメントデータを保存します
	        ByteArrayOutputStream out = new ByteArrayOutputStream();
	        document.save(out);
	        document.close();
	        
	        InputStream streamData =new ByteArrayInputStream(out.toByteArray());
	        
	        System.out.println("確認------------");
	        System.out.println("streamData" + streamData);
	    }
	    catch (Exception e) {
	        e.printStackTrace();
	    }
	}
}
```

このままblob型カラムなどに保存できます。

##作成したPDFから文字列を抽出する。

```
package pdf;

import java.io.File;
import java.io.StringWriter;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;

public class GetPdfText {

    public static void main(String args[]) {
	    try {
			
	    	String pdfFile = "test3.pdf";
	    	PDDocument document = PDDocument.load(new File(pdfFile));
	    	StringWriter output = new StringWriter();
	        PDFTextStripper stripper = new PDFTextStripper();
	    	stripper.setStartPage(1);
	    	stripper.setEndPage(1);
	    	stripper.setSortByPosition(false);
	    	stripper.setShouldSeparateByBeads(true);
	    	stripper.writeText(document, output);
	    	String content = output.toString();
	    	System.out.println("---------出力開始-------------");
	    	System.out.println(content);

		} catch (Exception e) {
			e.printStackTrace();
		}
    }
}
```

##実行結果
---------出力開始-------------
こんにちは世界

他にも画像埋め込みや罫線など、色々な機能がありますので、機会を見て追記していこうと思います。