【java】opencsv导出csv之后的数字格式问题解决
问题:某列其实你用记事本打开还是0001, 但是用excel打开是1,而且长数字比如身份证之类的,会变成十六位科学计算法,搞得很难看,而且csv的字符串左对齐,数字右对齐对于某些领导来说是不被看好的,所以如下文字解决此状况。opencsv导出csv之后的数字0消失的格式问题解决。
解决办法有两种:
1、在生成csv的时候,在数字的前面或后面加上"\t"制表符,再用excel打开问题解决!如 “1234567890”
2、在生成csv的时候,在数字的前面加上"=",再用excel打开问题解决!如 ="9876543210",=“1234567890”,
3 、对于EXCEL文件, 在禁止转义的内容前,加上一个半角单引号,' 符号
例子:
//测试
public void writeCsvWithRs (CsvHead head, CsvTitle title, ResultSet rs, String fname) throws IOException {
File tempFile = new File (fname);
CSVWriter writer = new CSVWriter (new FileWriter (tempFile) );
CsvField[] csvFields = null;
String[] titles = null;
try {
if (head != null) {
writer.writeNext (new String[] { head.getCompanyName() }); //公司号
writer.writeNext (new String[] { head.getDocDescription() }); //当前文档名
}
if (title != null) { //对传入的title做空值处理,表头
csvFields = title.getcsvFields();
titles = new String[csvFields.length];//这是我自己实现的逻辑,你可以不加这个
for (int i = 0, j = csvFields.length; i < j; i++) {
titles[i] = csvFields[i].getDescription();//获得描述
}
writer.writeNext ( (titles) ); //表头字段
}
writer.writeAll ( rsToList (rs) ); //数据体
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* rsToList (rs) 将结果集转成一个list<String[]>
*/
public List<String[]> rsToList (ResultSet rs) {
List<String> fields = null;//每一行
List<String[]> x = new ArrayList<String[]>();//存放每一行的总list,里面有N行
ResultSetMetaData rsmd;
try {
rsmd = rs.getMetaData();//rsmd你懂的
int columnCount = rsmd.getColumnCount(); //拿到多少列
// 输出数据 列的值
while (rs.next() ) {
fields = new ArrayList<String>();//rs的每一行结果集 生成一个list
for (int i = 1; i <= columnCount; i++) {
fields.add ("\t" + rs.getString (i) ); //把一行数据放入list,前面加入 \t
}
String[] fidldSt = (String[]) fields.toArray (new String[fields.size()]);//将list转成数组,方便写入csv
x.add (fidldSt);//加入总list中
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return x;//将存放所有数据行rs转化成String[]的x返回上去
}
ps : 另,今天老领导要求需要对csv里面的数据进行求和等二次处理,那么对于这种压榨程序员的工作,我们唯一的办法还是满足他们。。讲一下处理思路,对于这种csv还需要计算数字列,就要采取在数据库里面设置一个标志位是否是数字,isNumber 设置为true的话,就不处理,前面不加"\t",如果不是数字列,那么就是文本列,不需要参与计算,就处理一下,前面加"\t",程序如下:
public List<String[]> rsToList(ResultSet rs, CsvField[] csvFields) {
List<String> fields = null;
List<String[]> x = new ArrayList<String[]>();
ResultSetMetaData rsmd;
try {
rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount(); // 拿到多少列
// 输出列名
// for (int i=1; i<=columnCount; i++){
// System.out.print(rsmd.getColumnName(i)); //拿到列名,属性
// System.out.print("(" + rsmd.getColumnTypeName(i) +
// ")");//拿到对应的列的type
// }
// System.out.println();
// 输出数据 列的值
while (rs.next()) {
fields = new ArrayList<String>();
for (int i = 1; i <= columnCount; i++) {
log.info("csvFields[i].isNumber() = " + csvFields[i-1].isNumber());//数组从0开始读,rs从1开始的,所以 i-1
String data = rs.getString(i)==null?"":rs.getString(i);//空值处理
if(csvFields[i-1].isNumber()){//自己从数据库设置的字段判断是否数字列
fields.add(data);
}
else{
fields.add("\t"+data);// 把一行数据放入list
}
// System.out.print(rs.getString(i) + " | ");
}
// System.out.println("fields.size() = "+fields.size());
String[] fidldSt = (String[]) fields.toArray(new String[fields.size()]);
x.add(fidldSt);
// System.out.println();
}
/*
* for(int i=0;i<x.size();i++){ for(int j=0;j<
* x.get(i).size();j++){ // System.out.println(x.get(i).get(j)); }
* System.out.println(" "); }
*/
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return x;
}
效果图:
不知道怎么搞的就联系我
---------------------------------------------------
qq 394263788
专业java报表开发