内容
Spring Bootを使用したREST APIによるExcelダウンロードサンプルです。
Excelはテンプレートファイルをpoiで編集する形式です。
※テンプレートファイルはresources内に配置してください。
pom.xml
poiを導入する。
pom.xml
1 2 3 4 5 6 7 8 9 10 11 |
<!-- apache poi --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>4.0.1</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>4.0.1</version> </dependency> |
Service
Interface
ExcelBuildService.java
1 2 3 4 5 6 7 8 9 10 11 12 13 |
import org.apache.poi.ss.usermodel.Workbook; import org.springframework.web.server.ResponseStatusException; public interface ExcelBuildService { /** * Excelファイルを取得する。 * @return * @throws ResponseStatusException */ Workbook getExcel() throws ResponseStatusException; } |
Impl
@ValueにFileを指定すると、本番環境でjar内にresourcesを内包した場合にエラーとなるため、@ValueではResourceを指定してgetInputStream()で取得してます。
ExcelBuildServiceImpl.java
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 |
import org.apache.poi.ss.usermodel.*; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.Resource; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; import org.springframework.web.server.ResponseStatusException; @Service public class ExcelBuildServiceImpl implements ExcelBuildService{ @Value("classpath:excel/template.xlsx") private Resource templateResource; @Override public Workbook getExcel() throws ResponseStatusException { Workbook workbook; try { workbook = WorkbookFactory.create(templateResource.getInputStream()); } catch(Exception e) { throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR); } Sheet sheet = workbook.getSheetAt(0); getCell(sheet, 0, 0).setCellValue("1行1列"); getCell(sheet, 1, 0).setCellValue("2行1列"); getCell(sheet, 0, 1).setCellValue("1行2列"); return workbook; } /** * シート、行番号、列番号をしてセル情報を取得 * @param sheet シート * @param rowIndex 行番号(0から開始) * @param colIndex 列番号(0から開始) * @return セル */ private Cell getCell(Sheet sheet, int rowIndex, int colIndex) { Row row = sheet.getRow(rowIndex); if (row == null) { row = sheet.createRow(rowIndex); } Cell cell = row.getCell(colIndex); if (cell == null) { cell = row.createCell(colIndex); } return cell; } } |
Controller
ResponseEntityへ変換する箇所は、こちらを参考にしました。
DownloadController.java
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 |
import org.apache.poi.ss.usermodel.Workbook; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.*; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.server.ResponseStatusException; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; @Controller public class DownloadController { @Autowired ExcelBuildService excelBuildService; @GetMapping("/download") public HttpEntity downloadExcel() { return workbookToResponseEntity("ファイル名.xlsx", excelBuildService.getExcel()); } /** * workbookをResponseEntityに変換する。 * @param fileName * @param workbook * @return */ private ResponseEntity<byte[]> workbookToResponseEntity(String fileName, Workbook workbook) { String encodedFilename = null; try { encodedFilename = URLEncoder.encode(fileName, "UTF-8"); } catch (UnsupportedEncodingException e) { new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR); } ByteArrayOutputStream archivo = new ByteArrayOutputStream(); try { workbook.write(archivo); if(null!=workbook && null!=archivo) { workbook.close(); archivo.close(); } } catch(IOException e) { new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR); } byte[] documentContent = archivo.toByteArray(); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")); headers.set("Content-Disposition","attachment; filename*=UTF-8''" + encodedFilename); headers.setContentLength(documentContent.length); try { workbook.close(); archivo.close(); } catch(IOException e) { new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR); } return new ResponseEntity<byte[]>(documentContent, headers, HttpStatus.OK); } } |