You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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>节点,添加或修改encodingdefault-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

火山引擎 最新活动