Android导出含重音的SQLite数据到CSV时Google Sheets乱码问题
解决Android导出CSV含斯洛伐克语重音符号在Google Sheets乱码问题
你的核心问题是UTF-8编码识别失效,以及CSV格式细节未符合工具预期,导致Google Sheets无法正确解析重音字符。以下是具体修复方案:
1. 关键问题分析
- 你通过
BufferedWriter写入的BOM字符串无法生成正确的UTF-8字节序列,Google Sheets无法以此识别编码。 - 未对CSV字段做转义处理,特殊字符可能干扰解析逻辑,间接加剧编码识别偏差。
2. 修复步骤与代码实现
核心修改点
- 直接通过字节流写入UTF-8 BOM(
0xEF 0xBB 0xBF),确保编码标识不被字符流转码干扰。 - 使用
\r\n作为换行符,匹配多数表格工具的解析标准。 - 新增字段转义方法,处理含分号、双引号、换行的内容,避免解析错误。
修改后的完整代码
public Uri exportCSV(Context context) { String fileName = "my_data.csv"; ContentResolver resolver = context.getContentResolver(); Uri fileUri = null; ContentValues values = new ContentValues(); values.put(MediaStore.Downloads.DISPLAY_NAME, fileName); values.put(MediaStore.Downloads.MIME_TYPE, "text/csv"); values.put(MediaStore.Downloads.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS + "/osiva_export"); try { fileUri = resolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, values); if (fileUri == null) { return null; } OutputStream outputStream = resolver.openOutputStream(fileUri); if (outputStream == null) { return null; } // 写入标准UTF-8 BOM字节序列,强制Google Sheets识别编码 outputStream.write(new byte[]{(byte) 0xEF, (byte) 0xBB, (byte) 0xBF}); // 基于UTF-8创建字符写入流 BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream, StandardCharsets.UTF_8)); // 写入表头,使用规范换行符 writer.write(escapeCsvField("Názov rastliny") + ";" + escapeCsvField("Výrobca") + "\r\n"); SQLiteDatabase db = this.getReadableDatabase(); String query = "SELECT k.NAZOV, ..."; // 替换为你的完整查询语句 Cursor cursor = db.rawQuery(query, null); while (cursor.moveToNext()) { String plantName = cursor.getString(0); String manufacturer = cursor.getString(1); // 转义字段后拼接行内容 String line = escapeCsvField(plantName) + ";" + escapeCsvField(manufacturer) + "\r\n"; writer.write(line); } cursor.close(); writer.flush(); writer.close(); outputStream.close(); Log.i("CSV Export", "File successfully created with UTF-8 encoding: " + fileUri.toString()); return fileUri; } catch (IOException e) { e.printStackTrace(); return null; } } // CSV字段转义工具:处理含特殊字符的字段 private String escapeCsvField(String field) { if (field == null) { return ""; } // 若字段包含分号、双引号或换行,用双引号包裹并转义内部双引号 if (field.contains(";") || field.contains("\"") || field.contains("\n") || field.contains("\r")) { return "\"" + field.replace("\"", "\"\"") + "\""; } return field; }
3. 额外验证项
- 确认SQLite数据库编码:执行
PRAGMA encoding;查询,确保返回结果为UTF-8(SQLite默认使用UTF-8,旧数据库需额外确认)。 - 本地验证:用Notepad++等文本编辑器打开导出的CSV,确认编码为UTF-8且重音字符显示正常,再用Google Sheets打开测试。
内容的提问来源于stack exchange,提问作者Darksymphony
相关产品推荐
相关产品推荐

