Wildfly 17导出含中文Excel为CSV乱码问题及编码配置求助
解决Wildfly 17部署下Excel转CSV中文乱码问题
我来帮你搞定这个中文乱码的问题,咱们从代码修复和服务器编码配置调整两个维度来处理,先从最根本的代码问题入手,再配合服务器配置优化:
一、先修复代码里的潜在问题
你的代码里有两个会导致内容异常(包括中文乱码或内容丢失)的问题:
1. 公式单元格处理逻辑错误
原代码中case FORMULA分支没有添加break,导致公式计算后会直接落入default分支,把单元格值设为空。另外,公式单元格的类型判断需要先计算结果,再获取结果类型,而不是直接用原单元格的类型。优化后的单元格处理代码如下:
public class SplitterBean { public static final Logger LOGGER = LoggerFactory.getLogger(SplitterBean.class); public List<Map<String, String>> splitBody(XSSFWorkbook workbook) { LOGGER.info("Inside SplitterBean, splitting: " + workbook.getNumberOfSheets()); Map<String, String> sheetMap = null; List<Map<String, String>> sheetList = new ArrayList<>(); int numberOfSheets = workbook.getNumberOfSheets(); // 创建公式计算器 XSSFFormulaEvaluator evaluator = XSSFFormulaEvaluator.create(workbook); XSSFFormulaEvaluator.evaluateAllFormulaCells(workbook); for (int i = 0; i < numberOfSheets; i++) { StringBuilder sb = new StringBuilder(); sheetMap = new HashMap<>(); XSSFSheet sheet = workbook.getSheetAt(i); String sheetName = sheet.getSheetName(); for (Row row : sheet) { for (Cell cell : row) { String cellValueStr = ""; LOGGER.info("Cell type is: " + cell.getCellType()); switch (cell.getCellType()) { case NUMERIC: cellValueStr = Double.toString(cell.getNumericCellValue()); break; case STRING: cellValueStr = cell.getStringCellValue(); break; case BLANK: cellValueStr = ""; break; case FORMULA: LOGGER.info("Reached formula cell"); CellValue cellValue = evaluator.evaluate(cell); switch (cellValue.getCellType()) { case NUMERIC: cellValueStr = Double.toString(cellValue.getNumberValue()); break; case STRING: cellValueStr = cellValue.getStringValue(); break; case BLANK: cellValueStr = ""; break; default: cellValueStr = ""; break; } break; // 必须添加break,避免落入default分支 default: cellValueStr = ""; break; } sb.append(cellValueStr).append(","); } sb.append("\n"); } sheetMap.put(sheetName, sb.toString()); sheetList.add(sheetMap); } return sheetList; } }
2. 写入CSV时明确指定UTF-8编码
乱码的核心原因之一是写入文件时没有指定编码,默认使用了服务器的系统编码(可能不是UTF-8)。在将splitBody返回的内容写入CSV文件时,一定要用UTF-8编码,甚至可以添加UTF-8 BOM让Windows Excel正确识别编码:
// 示例:将sheetList写入CSV文件的逻辑 for (Map<String, String> sheetMap : sheetList) { for (Map.Entry<String, String> entry : sheetMap.entrySet()) { String sheetName = entry.getKey(); String csvContent = entry.getValue(); try (OutputStreamWriter osw = new OutputStreamWriter( new FileOutputStream(sheetName + ".csv"), StandardCharsets.UTF_8)) { // 添加UTF-8 BOM,解决Windows Excel打开UTF-8 CSV乱码的问题 osw.write('\ufeff'); osw.write(csvContent); } catch (IOException e) { SplitterBean.LOGGER.error("写入CSV文件失败:{}", sheetName, e); } } }
二、调整Wildfly 17的服务器编码配置
如果代码优化后仍有乱码问题,可以调整Wildfly的全局编码为UTF-8:
1. 修改启动脚本
- Linux/Unix:编辑
wildfly-17.0.1.FINAL/bin/standalone.conf,找到JAVA_OPTS配置,添加编码参数:JAVA_OPTS="$JAVA_OPTS -Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8" - Windows:编辑
wildfly-17.0.1.FINAL/bin/standalone.conf.bat,找到set "JAVA_OPTS="行,修改为:set "JAVA_OPTS=-Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8 %JAVA_OPTS%"
2. 修改standalone.xml配置
编辑wildfly-17.0.1.FINAL/standalone/configuration/standalone.xml:
- 找到Undertow子系统的
<http-listener>节点,添加或修改encoding和default-encoding属性:<http-listener name="default" socket-binding="http" redirect-socket="https" encoding="UTF-8" default-encoding="UTF-8"/> - 在
<servlet-container>节点添加default-encoding属性:<servlet-container name="default" default-encoding="UTF-8"> <!-- 原有内容保持不变 --> </servlet-container>
3. 重启Wildfly服务器
修改完成后,重启Wildfly让配置生效。
总结
优先修复代码里的公式处理bug和CSV写入编码问题,这是最可靠的解决方案;如果还是存在乱码,再调整服务器的编码配置。这两个层面结合,基本可以解决中文乱码问题。
内容的提问来源于stack exchange,提问作者Anirban




