1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

OpenPDFでPDFを作成して、ダウンロードまたはビューを表示させる

Posted at

今日も備忘録です。

このドキュメントについて

下記2点について記載していきます。

  1. PDFをダウンロード、ビュー表示させる方法
  2. OpenPDFを利用したPDF作成方法

※以下File操作系のクラスやメソッドについては、事前知識として必要
①:FileInputStream/FileOutputStreamクラス
②:Filesクラス
③:Pathクラスなど

実行環境

・Java17
・springboot 3.0.2

実装

①PDFをダウンロード、ビュー表示させる

PDFをダウンロードさせたり、ビュー表示させる方法は大きく分けて2つある。

方法① : HttpServletResponseを利用する

var response = new HttpServletResponse();
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "inline");

try(var inputStream = new BufferedInputStream(new FileInputStream(Fileクラス));
    var res = response.getOutputStream()) {
    res.write(inputStream.readAllBytes());
} catch (IOException e) {
    throw new RuntimeException("ファイル操作で問題発生", e);
}

説明:

  1. HttpServletResponseにContentTypeをpdfで設定する

  2. 1に合わせてContent-Dispositionに"inline"を設定する
    inlineは、ダウンロードではなくビューを表示する設定

  3. HttpServletResponseの出力ストリームを取得して、PDFのバイトデータを書き込む

※レスポンスの返却とかは不要

方法② : ResponseEntityを利用する

public ResponseEntity<byte[]> otherPdfDl(HttpServletResponse response) {
    var input = Paths.get("pdfを置いているパス");
    var respHeader = new HttpHeaders();
    respHeader.setContentType(MediaType.APPLICATION_PDF);
    respHeader.set(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=sample.pdf");

    try (var inputStream = new BufferedInputStream(new FileInputStream(Fileクラス))) {
        return new ResponseEntity<byte[]>(inputStream.readAllBytes(), respHeader, HttpStatus.OK);
    } catch (IOException e) {
            throw new RuntimeException("ファイル操作で問題発生", e);
    }
}

説明:

  1. HttpHeadersクラスをインスタンス化する

  2. ContentTypeをpdfを設定する

  3. 2に合わせてContent-Dispositionに"attachment"を設定する
    attachmentは、ダウンロードする設定

  4. ResponseEntityをインスタンス化し、引数に設定したヘッダー情報、PDFのバイトデータ、ステータスを設定する

出来上がったPDFを表示、ダウンロードさせるだけなら上記でOK!

②OpenPDFを利用してPDFを作成する

// gradle
implementation group: 'org.xhtmlrenderer', name: 'flying-saucer-pdf-openpdf', version: '9.1.11'
Path pdfTempFile = null;
try {
    pdfTempFile = Files.createTempFile("temp", ".pdf");
} catch (IOException e) {
    throw new RuntimeException("一時ファイル作成でエラーが発生しました", e);
}

var document = new Document();
PdfWriter pdfWriter = null;
try {
    pdfWriter = PdfWriter.getInstance(document, new BufferedOutputStream(new FileOutputStream(pdfTempFile.toFile())));
    var baseFont = BaseFont.createFont("HeiseiMin-W3", "UniJIS-UCS2-H", BaseFont.NOT_EMBEDDED);
    // タイトル用
    var titleFont = new Font(baseFont, 20f, Font.ITALIC, Color.RED);
    // 本文用
    var font = new Font(baseFont, 12f, java.awt.Font.PLAIN, Color.BLACK);
    document.open();
    document.add(new Paragraph("タイトル", titleFont));
    document.add(new Paragraph("内容", font));
    document.close();
    pdfWriter.close();
} catch (FileNotFoundException e) {
     throw new RuntimeException("ファイルが存在しません", e);
} catch (DocumentException e) {
      throw new RuntimeException("ドキュメント操作でエラーが発生しました", e);
} catch (IOException e) {
      throw new RuntimeException("ファイル操作でエラーが発生しました", e);
}

説明:

  1. 作成したPDFを一時的に置いておける一時ファイルを作成する
    Files.createTempFile(prefix, suffix)

  2. pdfWriterとdocumentのインスタンスを取得する
    ・pdfWriter:PDFドキュメントに対して直接書き込むためのAPIを提供
    ・document:PDFドキュメントを作成するためのベースクラス

  3. PDFへの書き込みで日本語が利用できないので、利用できるように設定
    ・UniJIS-UCS2-Hこれを設定することで、PDFに日本語が表示できる

  4. documentに内容をaddしていく、この時に第二引数にfontを設定

  5. pdfWriterとdocumentをcloseする
    ・closeする順番が違うと、PDFファイルに必要なすべての情報が書き込まれていないため、エラーが起こる。documentからcloseする

  6. 1で作成した一時ファイルにpdfが作成されているので、そのパスを使って後の処理をすれば、ダウンロードでもビュー表示でも可能

PDF作成の注意点

  1. 基本的にそのままでは日本語が利用できない。
    例えば、ファイル名でも日本語が利用できないので、URLEncoder.encode()を利用して、エンコードしてあげる必要がある。

  2. htmlを読み込んでPDFに落とし込む時は、ITextRendererを利用する必要がある?
    今回紹介したやり方ではhtmlをPDFにはめ込むことができなかった。
    ITextRendererを利用すると簡単にhtmlをはめこめた。

var render = new ITextRenderer();
render.setDocumentFromString(stringHtml);
render.layout();
render.createPDF(res);

まとめ

バイトデータをレスポンスに設定して返却する方法とHttpServletResponseに直接書き込む方法があることを学びました。
また、ビュー表示やダウンロードの方法やファイル名などに日本語を利用する時は、URLエンコードしないといけないことも学べました。

PDF作成やダウンロードの処理について、もっと簡単なやり方もあれば教えてほしいです。

1
1
1

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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?