csv文件导出注意事项
一、中文乱码问题
默认情况下,在windows上用excel打开csv文件时,并不是按utf-8码解析的,就算代码里设置了写入字符串为utf-8字符集,也可能乱码。
需要在文件头写入几个特殊的字节,做为utf-8的BOM头。
/** * utf-8的bom头 */ byte[] UTF8_HEADER_BOM = new byte[]{(byte) 0xEF, (byte) 0xBB, (byte) 0xBF};
建议导出后,用一些编辑工具查看16进制格式,确认前3个字节是否ef bb bf
二、大数字被显示为科学计数法的问题
一些产品编码,比如100000000001,打开后,会变成:
可在文本后加\t解决
三、海量数据写入时如何避免OOM
通常我们会把内容先拼成一个String,然后一次性写入,如果数据量巨大,比如上千万,一次性拼接很容易造成OOM。可以借用内存映射(NIO中的技术)优化。
RandomAccessFile file = new RandomAccessFile(csvFileName, "rw"); FileChannel channel = file.getChannel(); MappedByteBuffer mappedByteBuffer = channel.map(FileChannel.MapMode.READ_WRITE, file.length(), UTF8_HEADER_BOM.length); mappedByteBuffer.put(UTF8_HEADER_BOM);
完整示例:
/** * csv写入示例(菩提树下的杨过 http://yjmyzz.cnblogs.com) * * @throws IOException */ private static void testCsv() throws IOException { /** * utf-8的bom头 */ byte[] UTF8_HEADER_BOM = new byte[]{(byte) 0xEF, (byte) 0xBB, (byte) 0xBF}; String csvFileName = "D:\\temp\\test.csv"; FileUtils.deleteQuietly(new File(csvFileName)); RandomAccessFile file = new RandomAccessFile(csvFileName, "rw"); FileChannel channel = file.getChannel(); byte[] header = "编号,品名,时间戳\n".getBytes("UTF-8"); //写入utf8的bom头,防止打开csv时显示乱码 MappedByteBuffer mappedByteBuffer = channel.map(FileChannel.MapMode.READ_WRITE, file.length(), UTF8_HEADER_BOM.length); mappedByteBuffer.put(UTF8_HEADER_BOM); //写入标题栏 mappedByteBuffer = channel.map(FileChannel.MapMode.READ_WRITE, file.length(), header.length); mappedByteBuffer.put(header); //分批写入记录(每批1000条)-防止OOM long timestamp = System.currentTimeMillis(); for (int i = 1; i <= 100; i++) { StringBuilder sb = new StringBuilder(); for (int j = 1; j <= 1000; j++) { sb.append(i * j + "\t,"); sb.append("产品" + j + ","); sb.append(timestamp + "\t\n"); } byte[] data = sb.toString().getBytes("UTF-8"); mappedByteBuffer = channel.map(FileChannel.MapMode.READ_WRITE, file.length(), data.length); mappedByteBuffer.put(data); } //关闭通道 channel.close(); }
导出效果:
作者:菩提树下的杨过
出处:http://yjmyzz.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
出处:http://yjmyzz.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。