首页 > 解决方案 > 生成 PDF / XLSX 文件作为 REST API 的附件

问题描述

要求是在点击 REST API 端点时生成 pdf / excel 文档。即 localhost:8080/download.xlsx -> 生成数据为 .xlsx 格式的文件 localhost:8080/download.pdf -> 生成数据为 .pdf 格式的文件

Spring Boot 版本 - 2.0.2

由于我使用的是 Spring Boot 相对较新的版本,因此我必须实现 WebMvcConfigurer 而不是扩展 WebMvcConfigurerAdapter

我正在配置 ContentNegotiatingViewResolver

@Override
public void configureContentNegotiation(ContentNegotiationConfigurer 
 configurer) {
    configurer
            .favorPathExtension(true)
            .defaultContentType(MediaType.APPLICATION_JSON);
}

@Bean
public ViewResolver contentNegotiatingViewResolver(ContentNegotiationManager 
    manager) {
    ContentNegotiatingViewResolver resolver = new 
    ContentNegotiatingViewResolver();
    resolver.setContentNegotiationManager(manager);
    // Define all possible view resolvers
    List<ViewResolver> resolvers = new ArrayList<>();

    resolvers.add(excelViewResolver());
    resolvers.add(pdfViewResolver());

    resolver.setViewResolvers(resolvers);
    return resolver;
}

@Bean
public ViewResolver excelViewResolver() {
    return new ExcelViewResolver();
}

@Bean
public ViewResolver pdfViewResolver() {
    return new PdfViewResolver();
}

在我的控制器中: -

  @Controller
  public class MyController{

  @PostMapping(value = "/download", produces = {"application/pdf", 
  "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"})
public String downloadData(Model model, @RequestBody 
someRequestView requestView) {
    getSpringVersion();
    model.addAttribute("someResultList", 
    someService.extractDataForDownload(requestView));
    return "";
}
}

我什么都试过了,但是当我点击 localhost:8080/download.pdf -> 它给了我 404 not found 。请提出解决此问题的方法。

标签: spring-bootcontent-negotiation

解决方案


ExcelViewResolver 在最新版本中已被弃用。下面是一个以简单方式生成 Excel 文档的示例。

首先,创建一个 Excel 生成器类。根据要求配置列。并从数据库表中检索数据。

下面是示例 excel 生成器类。

public class StateExcelGenerator {

    public static ByteArrayInputStream statesToExcel(List<State> states) throws IOException {

        String[] COLUMNs = { "Id", "Name", "Desc" };

        try (Workbook workbook = new HSSFWorkbook(); ByteArrayOutputStream out = new ByteArrayOutputStream();) {
            CreationHelper createHelper = workbook.getCreationHelper();

            Sheet sheet = workbook.createSheet("StateInfo");

            Font headerFont = workbook.createFont();
            headerFont.setBold(true);
            headerFont.setColor(IndexedColors.BLUE.getIndex());

            CellStyle headerCellStyle = workbook.createCellStyle();
            headerCellStyle.setFont(headerFont);

            // Row for Header
            Row headerRow = sheet.createRow(0);

            // Header
            for (int col = 0; col < COLUMNs.length; col++) {
                Cell cell = headerRow.createCell(col);
                cell.setCellValue(COLUMNs[col]);
                cell.setCellStyle(headerCellStyle);
            }

            // CellStyle for Age
            CellStyle ageCellStyle = workbook.createCellStyle();
            ageCellStyle.setDataFormat(createHelper.createDataFormat().getFormat("#"));

            int rowIdx = 1;
            for (State state : states) {
                Row row = sheet.createRow(rowIdx++);

                row.createCell(0).setCellValue(state.getId());
                row.createCell(1).setCellValue(state.getName());
                row.createCell(2).setCellValue(state.getDesc());

            }

            workbook.write(out);
            return new ByteArrayInputStream(out.toByteArray());

        }

    }
}

现在修改您的控制器以处理下载文件,如下所示。

@Controller
@RequestMapping("/admin/state")
public class StateController {
    @RequestMapping(value = "/download/statedata.xlsx", method = RequestMethod.GET)
public ResponseEntity<InputStreamResource> excelCustomersReport() throws IOException {
    List<State> states = stateService.getData();

    ByteArrayInputStream in = StateExcelGenerator.statesToExcel(states);
    // return IOUtils.toByteArray(in);

    HttpHeaders headers = new HttpHeaders();
    headers.add("Content-Disposition", "attachment; filename=customers.xlsx");

    return ResponseEntity.ok().headers(headers).body(new InputStreamResource(in));
}
}

现在在您的视图页面中创建一个超链接,例如 jsp 文件,以访问上述控制器方法。

<a href="/admin/state/download/statedata.xlsx">Click here to download the file</a>

下面是下载的excel文件。

示例 Excel 下载文件


推荐阅读