我正在将使用Apache POI创建的Excel工作簿直接编写到响应对象,而不创建文件:
val outputStream: ByteArrayOutputStream = new ByteArrayOutputStream()
workbook.write(outputStream)
ExcelOk(response.getOutputStream.write(outputStream.toByteArray))
但是,一旦响应的大小超过8kB,它就会开始在Chrome中以zip
文件的形式下载,在FireFox中以octet-stream
下载。
我的ExcelOk
对象如下所示:
object ExcelOk {
def apply(body: Any = Unit, headers: Map[String, String] = ExcelContentType, reason: String = "") = {
halt(ActionResult(responseStatus(200, reason), body, headers ))
}
}
和我的ExcelContentType
(即响应标题)如下:
val ExcelContentType = Map(
"Access-Control-Allow-Credentials" -> "true",
"Access-Control-Allow-Methods" -> "GET, PUT, POST, DELETE, OPTIONS",
"Access-Control-Allow-Origin" -> "*",
"Access-Control-Max-Age" -> "1728000",
"Content-type" -> "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"Content-disposition" -> "attachment; filename=excel_report.xlsx"
)
我甚至尝试将"Transfer-Encoding" -> "chunked"
添加到标题列表中,但它不起作用。
我在我的web.xml
文件中添加了这个代码段,但它也没有帮助:
<mime-mapping>
<extension>xlsx</extension>
<mime-type>application/vnd.openxmlformats-officedocument.spreadsheetml.sheet</mime-type>
</mime-mapping>
对此有任何帮助都很有用。请注意,仅在响应大小超过特定阈值后才会观察到此行为。
答案 0 :(得分:1)
在将内容写入响应输出流之前,必须设置响应标头。
response.setHeader("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
response.setHeader("Content-disposition", "attachment; filename=excel_report.xlsx")
workbook.write(response.getOutputStream)