Java「itext」を使用して複数のPDFファイルを1つに連結する方法

Java

目次

バッチ処理などによって生成された複数のPDFファイルを、画面上の「一括印刷」ボタンが押下された際に、複数のファイルを1つにまとめることができたら便利です。

「一括印刷」のような機能が存在しない場合、ユーザはPDFファイルを1つずつ開いて「印刷」を行わなければなりません。

実際にやってみた

結論だけ知りたい方向けに、まずはソースコードをお見せいたします。

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;

import com.lowagie.text.Document;
import com.lowagie.text.pdf.PdfCopy;
import com.lowagie.text.pdf.PdfReader;

public class App {
	public static void main( String[] args ) {
		try (FileOutputStream fos = new FileOutputStream(
				new File("result_" + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + ".pdf"))){
			Document doc = new Document();
			PdfCopy copy = new PdfCopy(doc, fos);
			doc.open();

			PdfReader reader;
			for (File file : new File("./").listFiles(
					file -> file.getName().matches("Sheet.+\\.pdf"))) {
				reader = new PdfReader(new FileInputStream(file));
				for (int i = 1; i <= reader.getNumberOfPages(); i++) {
					// ページ数分ループ
					copy.addPage(copy.getImportedPage(reader, i));
				}
				reader.close();
			}

			doc.close();
		} catch (Exception e) {
			e.printStackTrace();
			System.exit(-1);
		}
	}
}

解説

13行目で出力ファイル名を定義しています。

固定の名前だと、本プログラムを再実行したときにエラーになってしまうため、ファイル名にタイムスタンプを付与しています。
「result_20190901123045.pdf」といったようなファイル名で出力されます。

また「try()」という構文はJava1.7から追加されたもので、「try resource構文」と言います。
このように記述することで、tryブロックを抜けた後、自動的にFileOutputStreamの「close()」メソッドがコールされます。
プログラムによるファイルの開きっぱなしを防止するために必要です。

15~17行目で出力ファイルをPDFファイルにするための設定を行っております。

20~21行目でコピー元のファイルを一覧形式で取得します。
File(“./”)で、プログラム実行時のカレントディレクトリを取得します。
Eclipseの場合、ワークスペースのプロジェクトフォルダの直下になります。

listFiles()で、対象フォルダ内のファイルの一覧を取得します。
引数にフィルターを設定することで、条件にマッチするファイルのみを取り出すことができます。
今回はファイル名が「Sheet○○.pdf」にマッチするファイルのみを条件としました。

また、上記の条件にマッチしたファイルを拡張for文で1つずつ取り出しています。

22行目で対象のPDFファイルを読み込みます。

25~27行目でPDFファイルのページ数を取得し、1ページずつコピー先にインポートします。
ページ番号は「1」から始まるため、for (i = 1~)というようにiも1からスタートします。

27行目で対象のPDFファイルをクローズします。

22~27行目を対象ファイル分ループさせることで、全てのファイルをコピー先にインポートしています。

全てのファイルのインポートが完了したため、30行目でPDFクローズします。

以上の処理を経ることにより、複数のPDFファイルを1つのファイルに連結することができます。

画像つき解説

Eclipseで「新規」→「mavenプロジェクト」で、新規プロジェクトを作成します。

プロジェクトおよびロケーションの選択はそのまま「次へ」

アーキタイプの選択もそのまま「次へ」

グループId、アーティファクトIDは適当に「test」と入力し、「完了」

プロジェクトが作成されたらpom.xmlを開き、dependencyに下記の追記を行います。バージョンは2019年9月時点のバージョンを記述しています。

pom.xmlを右クリックし、「実行」→「Maven install」

pom.xmlに記述された依存関係に基づき、ライブラリのインストールが行われます。

「BUILD SUCCESS」と表示されれば完了です。
これによりitextライブラリが使用できるようになりました。

PDFファイルを準備します。Excelを使用すればテスト用のPDFを簡単に出力することができます。
用意したPDFファイルはワークスペースのプロジェクトフォルダの直下に配置します。
※このフォルダが実行時のカレントディレクトリになります。

App.javaに冒頭のソースコードを貼り付けます。

「実行」→「実行構成」を選択します。

「Javaアプリケーション」を右クリックして「新規」

「実行」を押下します。

実行後、testフォルダ内にPDFファイルが新たに作成されています。

開いてみると2ページで構成されていることが確認できます。

1ページ目
2ページ目

まとめ

今回のプログラムは業務要件としてはニッチなものですが、この技術を知っているとユーザ側にとって使い勝手の良いシステムを構築できます。

itextはJavaでPDFを操作する際、とても重宝するライブラリです。
今回は既存のPDFファイルを連結させるだけのプログラムですが、新たにPDFを作成したりすることも可能です。

itextはとても便利なライブラリなので、Javaエンジニアとして是非マスターしておきたいライブラリですね。

コメント

タイトルとURLをコピーしました