最近在项目中,需要每天查询两个Sql语句,将结果存到文件中,并定时邮件发送给用户。为了方便使用的是csv格式,但是,得到的文件,用wps或者txt能正常打开,用excel打开乱码。
初步确定是java编码问题,发现保存的文件是utf-8格式,而excel打开csv默认是ANSI格式,在中文系统上默认的是GBK格式,因此准备将文件内容转码成GBK保存。但始终不能解决。
程序最开始的保存函数如下:
public void saveTofile(ResultSet rs,String path) throws SQLException, UnsupportedEncodingException, FileNotFoundException{
StringBuffer resu = new StringBuffer();
ResultSetMetaData m = rs.getMetaData();
int columns=m.getColumnCount();
//显示列,表格的表头
for(int i=1;i<=columns;i++)
{
resu.append(m.getColumnName(i));
if(i<columns)
resu.append(",");
else
resu.append("\r\n");
}
//显示表格内容
while(rs.next())
{
for(int i=1;i<=columns;i++)
{
resu.append(rs.getString(i));
if(i<columns)
resu.append(",");
else
resu.append("\r\n");
}
}
String result = new String(resu.toString());
//保存字符串到文件中
FileWriter fwriter = null;
try {
fwriter = new FileWriter(path);
fwriter.write(result, 0, result.length());
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
fwriter.flush();
fwriter.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
后面经过修改,转换编码格式为GBK保存的,如下:
result = new String(resu.toString().getBytes(), "GBK");
但是,此结果仍然出错。在程序中,将string转为GBK,再转回UTF-8,调试过程中,查看字符串,发现转换回来的字符串已经有部分乱码了,测试语句如下,不知道哪里逻辑出错:
result = new String(resu.toString().getBytes(), "GBK");
byte[] by = result.getBytes("GBK");
String ss = new String(by,"utf-8");
最后,查找开源程序,发现了如下链接中的代码:
http://www.oschina.net/code/snippet_161077_13341
经过下载相应的包,改写代码如下,证实完全能解决乱码:
public void saveTofile(ResultSet rs,String path) throws SQLException, FileNotFoundException{
StringBuffer resu = new StringBuffer();
ResultSetMetaData m = rs.getMetaData();
int columns=m.getColumnCount();
//显示列,表格的表头
for(int i=1;i<=columns;i++)
{
resu.append(m.getColumnName(i));
if(i<columns)
resu.append(",");
else
resu.append("\r\n");
}
//显示表格内容
while(rs.next())
{
for(int i=1;i<=columns;i++)
{
resu.append(rs.getString(i));
if(i<columns)
resu.append(",");
else
resu.append("\r\n");
}
}
byte commonCsvHead[] = { (byte) 0xEF, (byte) 0xBB,(byte) 0xBF };
try {
Files.write(Bytes.concat(commonCsvHead, resu.toString().getBytes(Charsets.UTF_8.toString())),
new File(path));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
这次的解决,对各种编码有了清楚的认识,不过花费了蛮久,以后得多参考开源代码。