找不到媒体类型= application / octet-stream的MessageBodyWriter,类型= class org.apache.poi.xssf.usermodel.XSSFWorkbook

时间:2018-05-17 21:24:11

标签: jersey apache-poi

我有下面的类试图以excel电子表格的形式返回一些数据。我收到了错误

  

找不到媒体类型= application / octet-stream的MessageBodyWriter,类型= class org.apache.poi.xssf.usermodel.XSSFWorkbook

我也尝试了@Produces("application/vnd.ms-excel"),但也遇到了类似的错误。有人建议如何让它返回电子表格吗?我最后一次收到类似于此的错误消息(抱怨无法找到arraylist的消息正文编写器)我只是将它包装在一个通用实体中。这一招并没有奏效。

@PermitAll
@Path("uploadWorkbook")
public class ExcelUploadResource {

    @Context
    ResourceContext resourceContext;

    @Inject
    JobService jobService;

    @GET
    @Produces(MediaType.APPLICATION_OCTET_STREAM)
    public Response list() {
        XSSFWorkbook workbook = new XSSFWorkbook();
        XSSFSheet sheet = workbook.createSheet("Job definitions");

        int rowNum = 0;
        for(Job job : jobService.list()){
            Row row = sheet.createRow(rowNum++);
            int cellNum = 0;
            for(String field : job.toList()){
                Cell cell = row.createCell(cellNum++);
                cell.setCellValue(field);
            }
        }

        GenericEntity<XSSFWorkbook> entity = new GenericEntity<XSSFWorkbook>(workbook) {};

        ResponseBuilder response = Response.ok(entity);
        response.header("Content-Disposition",
            "attachment; filename=jobs.xls");
        return response.build();
    }   
}

1 个答案:

答案 0 :(得分:3)

您不能只使用数据类型为application/octet-stream的任意对象。您首先需要了解的是对象是如何序列化的。这是通过使用MessageBodyWriter来完成的。您可以在JAX-RS Entity Providers中了解有关它们的更多信息。

作者的工作方式是传递实体和响应流。编写器应该接受实体并将实体的内容写入响应流。我们返回的实体类型和预期的媒体类型会查找编写器,在您的情况下,您希望它是application/octet-stream

错误的含义是没有作家来处理XSSFWorkbook的转换。当你谈到application/octet-stream时,你主要处理的是二进制文件。 XSSFWorkbook不是二进制文件。使用application/octet-stream时,您将主要使用byte[]FileInputStreamStreamingOutput实体类型。因此,如果您想使用application/octet-stream,那么您需要将实体更改为其中一种类型。

我从未使用过Apache POI,但只是通过一个快速教程,看起来你可能想要用于这种情况的是StreamingOutput,你可以使用XSSFWorkbook#write(OutputStream)方法将工作簿写入StreamingOutput

public Response getExcelFile() {
    XSSFWorkbook workbook = new XSSFWorkbook();
    ...
    StreamingOutput output = new StreamingOutput() {
        @Override
        public void write(OutputStream out)
                throws IOException, WebApplicationException {

            workbook.write(out);
            out.flush();
        }
    };
    return Response.ok(output)
            .header(HttpHeaders.CONTENT_DISPOSITION,
                    "attachment; filename=jobs.xls")
            .build();
}