在使用Spring Boot导出Excel或PDF报告时,常因响应头未正确设置字符编码导致中文乱码。典型问题出现在Controller返回文件流时,未指定`Content-Type`为`application/vnd.ms-excel;charset=UTF-8`,且未通过`URLEncoder`对文件名进行编码处理。尤其在Nginx代理或不同浏览器环境下,中文文件名更易出现乱码。此外,数据本身若未以UTF-8编码写入输出流,也会导致内容乱码。需综合配置响应头、文件名编码及IO流字符集,方可彻底解决。
2条回答 默认 最新
关注让【宝码香车】来帮您解答,本回答参考DeepSeek编写,并整理提供。
如果答案能帮助您,请采纳,非常感谢!
.
每日一句正能量,让它带给您好心情:别让别人的评价,左右你的人生,你才是自己的主角。
.在Spring Boot中解决导出报告时的中文乱码问题,需要从响应头设置、文件名编码和数据流编码三个方面进行综合处理。以下是具体的解决方案:
1. 设置正确的响应头
Excel文件导出
@RestController public class ReportController { @GetMapping("/export/excel") public ResponseEntity<byte[]> exportExcel(HttpServletResponse response) { try { // 设置响应头 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.parseMediaType("application/vnd.ms-excel;charset=UTF-8")); // 文件名编码处理 String fileName = URLEncoder.encode("中文报告.xlsx", "UTF-8"); headers.setContentDispositionFormData("attachment", fileName); headers.setCacheControl("no-cache"); // 生成Excel数据 byte[] excelData = generateExcelData(); return new ResponseEntity<>(excelData, headers, HttpStatus.OK); } catch (Exception e) { return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); } } }PDF文件导出
@GetMapping("/export/pdf") public ResponseEntity<byte[]> exportPdf() { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.parseMediaType("application/pdf;charset=UTF-8")); String fileName = URLEncoder.encode("中文报告.pdf", "UTF-8"); headers.setContentDispositionFormData("attachment", fileName); byte[] pdfData = generatePdfData(); return new ResponseEntity<>(pdfData, headers, HttpStatus.OK); }2. 兼容不同浏览器的文件名编码
public static String encodeFileName(HttpServletRequest request, String fileName) { try { String userAgent = request.getHeader("User-Agent"); String encodedFileName; if (userAgent != null && userAgent.contains("MSIE")) { // IE浏览器 encodedFileName = URLEncoder.encode(fileName, "UTF-8"); } else if (userAgent != null && userAgent.contains("Firefox")) { // Firefox浏览器 encodedFileName = new String(fileName.getBytes("UTF-8"), "ISO-8859-1"); } else { // 其他浏览器(Chrome、Safari等) encodedFileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20"); } return encodedFileName; } catch (UnsupportedEncodingException e) { return fileName; } }3. 确保数据流使用UTF-8编码
使用Apache POI导出Excel
private byte[] generateExcelData() throws IOException { Workbook workbook = new XSSFWorkbook(); Sheet sheet = workbook.createSheet("报告"); // 创建支持中文的字体 Font chineseFont = workbook.createFont(); chineseFont.setFontName("宋体"); chineseFont.setCharSet(Font.DEFAULT_CHARSET); // 创建单元格样式 CellStyle style = workbook.createCellStyle(); style.setFont(chineseFont); // 写入中文数据 Row row = sheet.createRow(0); Cell cell = row.createCell(0); cell.setCellValue("中文内容测试"); cell.setCellStyle(style); // 输出到字节数组 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); workbook.write(outputStream); workbook.close(); return outputStream.toByteArray(); }使用iText导出PDF
private byte[] generatePdfData() throws IOException { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); Document document = new Document(); PdfWriter.getInstance(document, outputStream); document.open(); // 设置中文字体 BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED); Font chineseFont = new Font(baseFont, 12, Font.NORMAL); // 写入中文内容 document.add(new Paragraph("中文报告内容", chineseFont)); document.add(new Paragraph("测试数据:中文显示正常", chineseFont)); document.close(); return outputStream.toByteArray(); }4. 全局配置解决字符编码问题
在application.yml中配置
spring: servlet: encoding: charset: UTF-8 enabled: true force: true http: encoding: charset: UTF-8 enabled: true force: true配置CharacterEncodingFilter
@Configuration public class EncodingConfig { @Bean public FilterRegistrationBean<CharacterEncodingFilter> characterEncodingFilter() { FilterRegistrationBean<CharacterEncodingFilter> filter = new FilterRegistrationBean<>(); filter.setFilter(new CharacterEncodingFilter()); filter.addInitParameter("encoding", "UTF-8"); filter.addInitParameter("forceEncoding", "true"); filter.addUrlPatterns("/*"); return filter; } }5. Nginx代理服务器配置
如果使用Nginx作为反向代理,需要在配置文件中添加字符编码设置:
server { listen 80; server_name your-domain.com; charset utf-8; location / { proxy_pass http://spring-boot-app; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # 确保字符编码正确传递 proxy_set_header Accept-Encoding ""; } }总结
解决Spring Boot导出中文乱码问题的关键步骤:
- 设置正确的Content-Type:包含字符编码信息
- 文件名编码处理:使用
URLEncoder对中文文件名进行编码 - 数据流编码:确保输出流使用UTF-8编码
- 浏览器兼容:针对不同浏览器采用相应的编码策略
- 代理服务器配置:确保Nginx等代理服务器正确传递字符编码
通过以上综合措施,可以有效解决Spring Boot导出报告时的中文乱码问题。
本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报