前回は、Sping BootのWEB画面上で、ファイルアップロード・ファイルダウンロード機能について記載したが、今回は、PDFの場合のみPDFプレビューを行うようにしたので、そのサンプルプログラムを共有する。
前提条件
下記記事の実装が完了していること。
Spring BootのWEB画面上でファイルアップロード・ダウンロード機能を実装してみた(ソースコード編)今回も引き続き、ファイルアップロード・ダウンロード機能の実装について述べる。ここでは、具体的なサンプルプログラムのソースコードを共有する...
完成イメージ
ここでは、完成した画面イメージの共有を行う。
Spring Bootアプリケーションを起動し、「http:// (ホスト名):(ポート番号)」とアクセスした場合の初期表示は以下の通りとする。
「PDFプレビュー」ボタンを押下すると、以下のように、別画面にPDFプレビュー画面が表示される。
作成したサンプルプログラムの内容
作成したサンプルプログラムの構成は以下の通り。なお、下図の赤枠は、前提条件に記載した記事と変更になったソースコードを示しており、今後記載する。
一覧画面を表示するプログラムは以下の通り。PDFの場合は「PDFプレビュー」ボタンを、それ以外の場合は「ダウンロード」ボタンを表示するようにしている。PDFの場合は、window.open関数を呼んでいて、新規画面を開くようにしている。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | <!DOCTYPE html> <html lang="ja" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>一覧画面</title> </head> <body> ファイルデータテーブル(file_data)の全データ<br/><br/> <table border="1" cellpadding="5"> <tr> <th>ID</th> <th>ファイルパス</th> <th></th> </tr> <tr th:each="obj : ${fileDataList}"> <td th:text="${obj.id}"></td> <td th:text="${obj.filePath}"></td> <td> <!-- ダウンロードボタンを表示 --> <!-- PDFファイルの場合 --> <div th:if=${#strings.endsWith(obj.filePath,'.pdf')}> <input type="button" value="PDFプレビュー" th:onclick="'window.open(\'/download?id=' + ${obj.id} + '\', target=\'_blank\');'" /> </div> <!-- PDFファイル以外の場合 --> <div th:unless=${#strings.endsWith(obj.filePath,'.pdf')}> <form action="#" method="get" th:action="@{/download(id=${'__${obj.id}__'})}" th:method="download" > <input type="hidden" name="_method" value="download" /> <input type="submit" value="ダウンロード" /> </form> </div> </td> </tr> </table> <br/><br/> <form method="post" th:action="@{/to_add}"> <input type="submit" value="データ追加" /><br/><br/> <input type="button" value="閉じる" onclick="window.close();" /> </form> </body> </html> |
さらに、ダウンロード処理を含むコントローラクラスのプログラムは以下の通り。downloadメソッドが変更点である。PDFとそれ以外で処理を分け、PDFの場合は、ContentTypeを「application/pdf」に設定し「Content-Disposition」をinlineにすることで、(新しく開いた画面に)PDFプレビュー画面を開くようにしている。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | package com.example.demo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.multipart.MultipartFile; import org.springframework.transaction.annotation.Transactional; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.InputStream; import java.io.OutputStream; import java.net.URLEncoder; import java.util.List; @Controller public class DemoController { /** * ファイルデータテーブル(file_data)へアクセスするMapper */ @Autowired private FileDataMapper fileDataMapper; /** * ファイルデータ一覧表示処理 * @param model Modelオブジェクト * @return 一覧画面 */ @RequestMapping("/") public String index(Model model){ //ファイルデータテーブル(file_data)を全件取得 List<FileData> list = fileDataMapper.findAll(); model.addAttribute("fileDataList", list); //一覧画面へ移動 return "list"; } /** * ファイルデータ登録画面への遷移処理 * @return ファイルデータ登録画面 */ @PostMapping("/to_add") public String to_add(){ return "add"; } /** * ファイルデータ登録処理 * @param uploadFile アップロードファイル * @return ファイルデータ一覧表示処理 */ @PostMapping("/add") @Transactional(readOnly = false) public String add(@RequestParam("upload_file") MultipartFile uploadFile){ //最大値IDを取得 long maxId = fileDataMapper.getMaxId(); //追加するデータを作成 FileData fileData = new FileData(); fileData.setId(maxId + 1); fileData.setFilePath(uploadFile.getOriginalFilename()); try{ fileData.setFileObj(uploadFile.getInputStream()); }catch(Exception e){ System.err.println(e); } //1件追加 fileDataMapper.insert(fileData); //一覧画面へ遷移 return "redirect:/to_index"; } /** * 追加完了後に一覧画面に戻る * @param model Modelオブジェクト * @return 一覧画面 */ @GetMapping("/to_index") public String toIndex(Model model){ return index(model); } /** * ファイルダウンロード処理 * @param id ID * @param response HttpServletResponse * @return 画面遷移先 */ @RequestMapping("/download") public String download(@RequestParam("id") String id , HttpServletResponse response){ //ダウンロード対象のファイルデータを取得 FileData data = fileDataMapper.findById(Long.parseLong(id)); //ダウンロード対象のファイルデータがnullの場合はエラー画面に遷移 if(data == null || data.getFileObj() == null){ return "download_error"; } //PDFの場合 if(data.getFilePath().endsWith(".pdf")){ //PDFプレビューの設定を実施 response.setContentType("application/pdf"); response.setHeader("Content-Disposition", "inline;"); }else{ //ファイルダウンロードの設定を実施 //ファイルの種類は指定しない response.setContentType("application/octet-stream"); response.setHeader("Content-Disposition" ,"attachment;filename=\"" + getFileName(data.getFilePath()) + "\""); } //その他の設定を実施 response.setHeader("Cache-Control", "private"); response.setHeader("Pragma", ""); try(OutputStream out = response.getOutputStream(); InputStream in = data.getFileObj()){ byte[] buff = new byte[1024]; int len = 0; while ((len = in.read(buff, 0, buff.length)) != -1) { out.write(buff, 0, len); } out.flush(); }catch(Exception e){ System.err.println(e); } //画面遷移先はnullを指定 return null; } /** * ファイルパスからファイル名を取得する * @param filePath ファイルパス * @return ファイル名 */ private String getFileName(String filePath){ String fileName = ""; if(filePath != null && !"".equals(filePath)){ try{ //ファイル名をUTF-8でエンコードして指定 fileName = URLEncoder.encode(new File(filePath).getName(), "UTF-8"); }catch(Exception e){ System.err.println(e); return ""; } } return fileName; } } |
その他のソースコード内容は、以下のサイトを参照のこと。
https://github.com/purin-it/java/tree/master/spring-boot-pdf-preview/demo
要点まとめ
- ContentTypeを「application/pdf」に設定し、「Content-Disposition」をinlineにすることで、PDFプレビュー表示が行える。