From 05eba770a2533a173da4dfe479dc9e8044b1c768 Mon Sep 17 00:00:00 2001 From: duhuafei Date: Wed, 26 Jun 2019 14:39:08 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E6=96=B0=E5=A2=9ERFC=205987=E6=A0=87?= =?UTF-8?q?=E5=87=86=E6=96=87=E4=BB=B6=E5=90=8Dheader:content-disposition?= =?UTF-8?q?=E7=94=9F=E6=88=90=E5=B7=A5=E5=85=B7=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../easypoi/util/WebFilenameUtils.java | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 easypoi-base/src/main/java/cn/afterturn/easypoi/util/WebFilenameUtils.java 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); + + } +} From 3ee5b70a854393c617f219f535fddba2773c72dd Mon Sep 17 00:00:00 2001 From: duhuafei Date: Wed, 26 Jun 2019 14:39:35 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E4=BF=AE=E6=94=B9PDF=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=90=8D=E8=AE=BE=E7=BD=AEcontent-disposition=E7=94=9F?= =?UTF-8?q?=E6=88=90=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../afterturn/easypoi/view/EasypoiPDFTemplateView.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) 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); } From c2b07061852d66589b2ae30127ce5ad1a643aa66 Mon Sep 17 00:00:00 2001 From: duhuafei Date: Wed, 26 Jun 2019 14:39:58 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E4=BF=AE=E6=94=B9Word=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=90=8D=E8=AE=BE=E7=BD=AEcontent-disposition=E7=94=9F?= =?UTF-8?q?=E6=88=90=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../afterturn/easypoi/view/EasypoiTemplateWordView.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) 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)); From 6037600d494b99d333cd9dca661ab61a14e88c6d Mon Sep 17 00:00:00 2001 From: duhuafei Date: Wed, 26 Jun 2019 14:40:27 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E4=BF=AE=E6=94=B9Excel=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=90=8D=E8=AE=BE=E7=BD=AEcontent-disposition=E7=94=9F?= =?UTF-8?q?=E6=88=90=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/afterturn/easypoi/view/MiniAbstractExcelView.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) 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();