diff --git a/easypoi-base/src/main/java/cn/afterturn/easypoi/util/WebFilenameUtils.java b/easypoi-base/src/main/java/cn/afterturn/easypoi/util/WebFilenameUtils.java new file mode 100644 index 0000000..d447617 --- /dev/null +++ b/easypoi-base/src/main/java/cn/afterturn/easypoi/util/WebFilenameUtils.java @@ -0,0 +1,37 @@ +package cn.afterturn.easypoi.util; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.UnsupportedEncodingException; + +/**根据RFC 5987规范生成disposition值, 解决浏览器兼容以及中文乱码问题 + * @author halfdo + * @date 6/25/2019 + */ +public class WebFilenameUtils { + + private static final Logger LOGGER = LoggerFactory.getLogger(WebFilenameUtils.class); + + private static final String DISPOSITION_FORMAT = "attachment; filename=\"%s\"; filename*=utf-8''%s"; + + /** + * 未编码文件名转Content-Disposition值 + * + * @param filename 未编码的文件名(包含文件后缀) + * @return Content-Disposition值 + */ + public static String disposition(String filename) { + String codedFilename = filename; + try { + if (StringUtils.isNotBlank(filename)) { + codedFilename = java.net.URLEncoder.encode(filename, "UTF-8"); + } + } catch (UnsupportedEncodingException e) { + LOGGER.error("不支持的编码:", e); + } + return String.format(DISPOSITION_FORMAT, codedFilename, codedFilename); + + } +} diff --git a/easypoi-web/src/main/java/cn/afterturn/easypoi/view/EasypoiPDFTemplateView.java b/easypoi-web/src/main/java/cn/afterturn/easypoi/view/EasypoiPDFTemplateView.java index a889d51..5fc3348 100644 --- a/easypoi-web/src/main/java/cn/afterturn/easypoi/view/EasypoiPDFTemplateView.java +++ b/easypoi-web/src/main/java/cn/afterturn/easypoi/view/EasypoiPDFTemplateView.java @@ -23,6 +23,7 @@ import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import cn.afterturn.easypoi.util.WebFilenameUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Controller; @@ -70,12 +71,8 @@ public class EasypoiPDFTemplateView extends PoiBaseView { if (StringUtils.isNoneBlank(userFileName)) { fileName = userFileName; } - if (isIE(request)) { - fileName = java.net.URLEncoder.encode(fileName, "UTF8"); - } else { - fileName = new String(fileName.getBytes("UTF-8"), "ISO-8859-1"); - } - response.setHeader("content-disposition", "attachment;filename=" + fileName + ".pdf"); + // 用工具类生成符合RFC 5987标准的文件名header, 去掉UA判断 + response.setHeader("content-disposition", WebFilenameUtils.disposition(fileName + ".pdf")); writeToResponse(response, baos); } diff --git a/easypoi-web/src/main/java/cn/afterturn/easypoi/view/EasypoiTemplateWordView.java b/easypoi-web/src/main/java/cn/afterturn/easypoi/view/EasypoiTemplateWordView.java index 2298be7..56f8a6d 100644 --- a/easypoi-web/src/main/java/cn/afterturn/easypoi/view/EasypoiTemplateWordView.java +++ b/easypoi-web/src/main/java/cn/afterturn/easypoi/view/EasypoiTemplateWordView.java @@ -21,6 +21,7 @@ import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import cn.afterturn.easypoi.util.WebFilenameUtils; import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.springframework.stereotype.Controller; @@ -50,12 +51,8 @@ public class EasypoiTemplateWordView extends PoiBaseView { if (model.containsKey(TemplateWordConstants.FILE_NAME)) { codedFileName = (String) model.get(TemplateWordConstants.FILE_NAME) + ".docx"; } - if (isIE(request)) { - codedFileName = java.net.URLEncoder.encode(codedFileName, "UTF8"); - } else { - codedFileName = new String(codedFileName.getBytes("UTF-8"), "ISO-8859-1"); - } - response.setHeader("content-disposition", "attachment;filename=" + codedFileName); + // 用工具类生成符合RFC 5987标准的文件名header, 去掉UA判断 + response.setHeader("content-disposition", WebFilenameUtils.disposition(codedFileName)); XWPFDocument document = WordExportUtil.exportWord07( (String) model.get(TemplateWordConstants.URL), (Map) model.get(TemplateWordConstants.MAP_DATA)); diff --git a/easypoi-web/src/main/java/cn/afterturn/easypoi/view/MiniAbstractExcelView.java b/easypoi-web/src/main/java/cn/afterturn/easypoi/view/MiniAbstractExcelView.java index 5740693..04ca2c3 100644 --- a/easypoi-web/src/main/java/cn/afterturn/easypoi/view/MiniAbstractExcelView.java +++ b/easypoi-web/src/main/java/cn/afterturn/easypoi/view/MiniAbstractExcelView.java @@ -15,6 +15,7 @@ */ package cn.afterturn.easypoi.view; +import cn.afterturn.easypoi.util.WebFilenameUtils; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.Workbook; @@ -46,12 +47,8 @@ public abstract class MiniAbstractExcelView extends PoiBaseView { } else { codedFileName += XSSF; } - if (isIE(request)) { - codedFileName = java.net.URLEncoder.encode(codedFileName, "UTF8"); - } else { - codedFileName = new String(codedFileName.getBytes("UTF-8"), "ISO-8859-1"); - } - response.setHeader("content-disposition", "attachment;filename=" + codedFileName); + // 用工具类生成符合RFC 5987标准的文件名header, 去掉UA判断 + response.setHeader("content-disposition", WebFilenameUtils.disposition(codedFileName)); ServletOutputStream out = response.getOutputStream(); workbook.write(out); out.flush();