Java SDK将Excel转CSV上传S3后下载打开乱码如何修复
问题修复方案
核心错误原因
你当前的代码没有将Excel工作簿转换为CSV格式,只是直接输出了XLSX格式的二进制压缩流,却错误标记了text/csv的内容类型,XLSX本身是二进制压缩文件,直接作为文本打开自然会出现乱码。
修复步骤
- 第一步:补充Excel转CSV的逻辑,你可以通过Apache POI遍历Excel单元格内容,拼接为符合CSV规范的文本,也可以引入
opencsv等工具类简化转换操作。 - 第二步:将转换后的CSV文本以UTF-8编码写入字节流,避免使用系统默认编码导致的额外乱码问题。
- 第三步:保持S3上传的内容类型配置为
text/csv; charset=utf-8即可,若需要适配Windows记事本的中文显示,可在CSV内容开头添加UTF-8 BOM头(0xEF 0xBB 0xBF)。
修正后代码示例
import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.AmazonS3ClientBuilder; import com.amazonaws.services.s3.model.ObjectMetadata; import com.amazonaws.services.s3.model.PutObjectRequest; import com.amazonaws.services.s3.model.PutObjectResult; import java.io.*; import java.nio.charset.StandardCharsets; public boolean exportFileToS3(XSSFWorkbook workbook) throws Exception{ // 先将Excel转换为CSV格式文本 StringBuilder csvContent = new StringBuilder(); // 可选:添加UTF-8 BOM头适配Windows记事本 csvContent.append('\ufeff'); // 遍历Excel第一个sheet(可根据需求遍历所有sheet) Sheet sheet = workbook.getSheetAt(0); for (Row row : sheet) { for (int i = 0; i < row.getLastCellNum(); i++) { if (i > 0) { csvContent.append(","); } Cell cell = row.getCell(i); // 处理不同类型的单元格值,可根据需求扩展 String cellValue = ""; if (cell != null) { switch (cell.getCellType()) { case STRING: cellValue = cell.getStringCellValue(); // CSV字段含逗号/引号时需要转义 if (cellValue.contains(",") || cellValue.contains("\"")) { cellValue = "\"" + cellValue.replace("\"", "\"\"") + "\""; } break; case NUMERIC: if (DateUtil.isCellDateFormatted(cell)) { cellValue = cell.getDateCellValue().toString(); } else { cellValue = String.valueOf(cell.getNumericCellValue()); } break; case BOOLEAN: cellValue = String.valueOf(cell.getBooleanCellValue()); break; default: cellValue = ""; } } csvContent.append(cellValue); } csvContent.append("\n"); } // 将CSV文本转为UTF-8编码的字节流 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); try { byteArrayOutputStream.write(csvContent.toString().getBytes(StandardCharsets.UTF_8)); byteArrayOutputStream.close(); } catch (Exception e) { System.out.println("convert to CSV error ", e); throw e; } //AWS Credential AmazonS3 s3client = AmazonS3ClientBuilder .standard() .withCredentials(new AWSStaticCredentialsProvider(mycredential)) .withRegion(myregion) .build(); // 上传逻辑保持不变 ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); Long contentLength = Long.valueOf(byteArrayOutputStream.toByteArray().length); ObjectMetadata objectMetadata = new ObjectMetadata(); objectMetadata.setContentType("text/csv; charset=utf-8"); objectMetadata.setContentLength(contentLength); String bucketName = "my bucket"; String fileName = "test.csv"; PutObjectResult putResult = s3client.putObject(new PutObjectRequest(bucketName, fileName, byteArrayInputStream, objectMetadata)); byteArrayInputStream.close(); return (putResult != null); }
内容的提问来源于stack exchange,提问作者Hanh Nguyen
相关产品推荐
相关产品推荐

