[英]Using XSSFWorkbook and AbstractExcelView
我的理解是 AbstractExcelView 類函數 buildExcelDocument 不支持 XSSFWorkbook ( https://jira.spring.io/browse/SPR-6898 )。
我試圖通過實現 buildExcelDocument 函數來解決這個問題,如下所示:
Workbook workbook = null;
protected void buildExcelDocument(Map model,
HSSFWorkbook wbook,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
if(request.getRequestURL().toString().contains("xlsx")){
workbook = new XSSFWorkbook();
workbook.createSheet();
excelVersion = "xlsx"; //Used to determine response
}else{
workbook = wbook;
}
buildBothExcelDocument(model,workbook,request,response);
}
在這里,我的 buildBothExcelDocument 函數將使用 Apache SS 用戶模型來生成和創建兩個 Excel 版本,HSSFWorkbook 和 XSSFWorkbook。 創建工作簿后,我將創建一個標題,提示用戶保存或打開 excel 文件:
if(excelVersion.equals("xlsx")){
response.setHeader("Pragma", "public");
response.setHeader("Cache-Control", "max-age=0");
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=test.xlsx");
}else{
response.setHeader("Pragma", "public");
response.setHeader("Cache-Control", "max-age=0");
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment; filename=\"test.xls\"");
}
所有上述代碼在使用 HSSFWorkbook 時都有效。 工作簿的數據被正確創建,可以下載,並且可以使用 Microsoft Excel 2003 或 Microsoft Excel 2007 正確打開。
當我嘗試創建 .xlsx 文件時,我在打開時收到一條錯誤消息,指出“Excel 無法打開文件 'test.xlsx',因為文件格式或文件擴展名無效。請確認文件沒有損壞,並且文件擴展名與文件格式匹配”。 這讓我相信 Spring 的某個地方損壞了我的文件。 我的問題是:
1 - 我的響應內容類型和標題是否正確? (來源: excel 文件的正確內容類型是什么? )
2 - 有沒有辦法使用 Spring 和 AbstractExcelView 創建 xlsx excel 文件?
3 - Spring 是否完全支持 XSSFWorkbook?
一些補充說明:
Apache POI 版本 - v3.9
創建標頭時,我嘗試了以下操作:
response.setHeader("Content-Disposition", "attachment; filename=\"test.xlsx\"");
和
response.setHeader("Content-Disposition", "attachment; filename='test.xlsx'");
都產生相同的失敗結果。
我使用以下鏈接幫助將我的舊 HSSF 代碼轉換為使用 SS 用戶模型, http: //poi.apache.org/spreadsheet/converting.html。 我在沒有 Spring 干擾的情況下測試了這個轉換過程,並且能夠成功創建 xls 和 xlsx 文件。 謝謝您的幫助。
您可以創建自定義 AbstractExcelView 並從該類擴展您的視圖。 請參閱下面的示例代碼。
import java.io.ByteArrayOutputStream;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.servlet.view.AbstractView;
public abstract class CustomAbstractExcelView extends AbstractView {
@Override
protected boolean generatesDownloadContent() {
return true;
}
@Override
protected final void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
final ByteArrayOutputStream baos = createTemporaryOutputStream();
final Workbook workbook = new XSSFWorkbook();
this.buildExcelDocument(model, workbook, request, response);
workbook.write(baos);
this.writeToResponse(response, baos);
}
protected abstract void buildExcelDocument(Map<String, Object> model, Workbook workbook, HttpServletRequest request, HttpServletResponse response) throws Exception;
}
我知道 POI 的 .Net 實現有一種寫入流的方法。 如果您將 Workbook 接口寫入 Stream,並將流作為帶有參數內容和標頭的字節數組返回,它應該可以工作——我在 .Net MVC 控制器中遇到了類似的問題,無法正確提供響應。
請確保您提供的內容類型正確,
(" application/vnd.openxmlformats-officedocument.spreadsheetml.sheet "); 生成與 MS Office 2007 onwords 兼容的.xlsx格式的 Excel
(" application/vnd.ms-excel ");->生成.xls格式的excel
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.