在Scalatra中将Excel下载为xlsx而不是zip格式

时间:2017-07-25 14:56:28

标签: web.xml scalatra

我正在将使用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>

对此有任何帮助都很有用。请注意,仅在响应大小超过特定阈值后才会观察到此行为。

1 个答案:

答案 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)