10
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JavaでPDF操作してみたい

Last updated at Posted at 2024-12-27

はじめに

ふとJavaでPDFファイルを操作できないかと調べたところ、Apache PDFBoxライブラリが便利そうだということがわかりました。この記事では、PDFBoxを使って何ができるのか備忘録としてまとめていきます。

Mavenプロジェクトに追加

まずは、PDFBoxを使えるようにするため依存関係を追加します。

pom.xml
<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox</artifactId>
    <version>3.0.3</version>
</dependency>

PDFファイルの作成

下記はPDFファイルを作成できた処理です。
実行結果も載せています。

PdfApplication.java
package com.example.pdf;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

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

public class PdfApplication {
	
	public static final String PATH = "出力先のパス";

	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.setFont(new PDType1Font(Standard14Fonts.FontName.COURIER), 20);
            contentStream.beginText();
            contentStream.newLineAtOffset(0, 0);
            contentStream.showText("This is a PDF file");
            contentStream.endText();
            
            contentStream.close();

            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss");
            String timestamp = LocalDateTime.now().format(formatter);
            String fileName = "sample_" + timestamp + ".pdf";
            
            document.save(PATH + fileName);
            document.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

こちらが作成したPDFです。
pdf1.png

PDDocumentクラス

PDDocument document = new PDDocument();

PDFドキュメント全体を管理するための基本的なクラスです。インスタンスを作成した時点では空なので、ページを追加する必要があります。

メソッド例

  • addPage(PDPage page)
    • 指定したページをドキュメントに追加します
  • removePage(PDPage page)
    • 指定したページをドキュメントから削除します
  • removePage(int pageNumber)
    • インデックス(0始まり)を指定してページをドキュメントから削除します
  • save(String fileName)
    • ドキュメントを指定したファイル名で保存します
  • close()
    • ドキュメントの操作を終了し、関連するリソースを解放します

PDPageクラス

PDPage page = new PDPage();

PDFの1ページを表しているクラスです。デフォルトで設定されているページのサイズはU.S. Letter (8.5 x 11 inches)です。
例えばA4サイズで作成したい場合は下記のように記述します。

PDRectangle pageSize = PDRectangle.A4;
PDPage page = new PDPage(pageSize);

PDPageContentStreamクラス

PDPageContentStream contentStream = new PDPageContentStream(document, page);

ページにコンテンツ(テキストなど)を描画するためのクラスです。
メソッド例

  • setFont(PDType1Font font, float size)
    • フォントとサイズを設定します
  • beginText()
    • テキスト描画を開始します
  • newLineAtOffset(float x, float y)
    • テキストを描画する位置を指定します
  • showText(String text)
    • 実際にテキストをページ上に描画します
  • endText()
    • テキスト描画を終了します
  • close()
    • コンテンツストリームを閉じて、ページへの描画を完了します

描画位置

(0, 0)と指定することで左上に描画される想定でしたが、実際に出力した結果は左下でした。

contentStream.newLineAtOffset(0, 0);

左上を指定する場合のy座標はページの高さを用いて計算します。
(0, pageHeight)にすると文字がページ外はみ出してしまったのでフォントのサイズ分下げてみました。

// ページの高さを取得
float pageHeight = page.getMediaBox().getHeight();
contentStream.newLineAtOffset(0, pageHeight - 20);

これで左上に揃えることができました。
pdf2.png

複数ページ

複数ページ作成したいときはPDPageインスタンスを複数生成します。
2ページ目はA4を指定しサイズが異なることも確認できました。

PDPage page = new PDPage();
document.addPage(page);
			
PDRectangle pageSize = PDRectangle.A4;
PDPage page2 = new PDPage(pageSize);
document.addPage(page2);

pdf3.png

画像を描画

テキストだけではなく画像を描画することもできました。
こちらも(0, 0)だと左下の位置を指定するようです。

File imageFile = new File(IMAGE_PATH);
PDImageXObject image = PDImageXObject.createFromFile(imageFile.getAbsolutePath(), document);

PDPageContentStream contentStream2 = new PDPageContentStream(document, page2);

contentStream2.drawImage(image, 0, 0);
contentStream2.close();

pdf5.png

PDFの読み込み

既存のPDFを読み込むこともできます。
新しいファイルとしてPDFを読み込み、さらにページを複製してみました。

File file = new File("任意のパス");
PDDocument document = Loader.loadPDF(file);

// 既存のPDFの1ページ目を取得
PDPage page = document.getPage(0);

// 新しいページを作成
document.importPage(page);

2ページ目ができています。
pdf6.png

あとがき

ttfファイルを読み込んでフォントを好きなように変えてみたかったのですがそれは次回試してみます。

Apache PDFBoxのバージョン3前後で処理内容が結構変わっているようですね。

10
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?