需求:美国56个州的数据存入excel文件,一个州对应一个表格。。
最开始的写法是存成.xlsx格式,这是数据组让做的。。原因是他怕数据掉了。。。因为这个xlsx格式,劳资的心快碎成了渣渣。。
最开始的写法:
for(int i=0;i<jsonArray.size();i++) {
int colunm = 0;
row = sheet.createRow(sheet.getLastRowNum()+1);
JSONObject jsonObject = jsonArray.getJSONObject(i);
JSONObject attributes = null;
// JSONObject geometry = null;
if(jsonObject != null){
attributes = jsonObject.getJSONObject("attributes");
// geometry = jsonObject.getJSONObject("geometry");
}
if(attributes == null){
continue;
}
Iterator<?> attributesKeys = attributes.keySet().iterator();
while (attributesKeys.hasNext()) {
String key = (String) attributesKeys.next();
String value = format(attributes.get(key) == null ? null : attributes.getString(key));
cell = row.createCell(colunm);
cell.setCellValue(value);
colunm ++;
}
cell = row.createCell(colunm);
cell.setCellValue("");
cell = row.createCell(colunm+1);
cell.setCellValue("");
cell = row.createCell(colunm+2);
cell.setCellValue(state);
}
File file = new File("dataFiles/"+state+".xlsx");
if(!file.exists()) {
file.createNewFile();
}
outputStream = new FileOutputStream(file);
workbook.write(outputStream);
outputStream.close();
最开始写成功这个方法也废了不少力气,因为poi的jar包不知道为啥要和几个看起来不太相关的jar包一起放上去才有用。。我也不清楚原因。。代码里好像也没有引用,但是你不加上去,它就报错。。然后你去百度错误他就会说是缺jar包。。。有无赖那味了是不是。。。
以上这种写法对于数据量少点的基本没问题,因为我前两个数据少的州都写成功了,但是遇上一个州几十万条。。。就会报这种错误:
Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded at java.lang.Double.toString(Double.java:179) at java.lang.String.valueOf(String.java:2973) at java.lang.Double.toString(Double.java:603) at java.lang.String.valueOf(String.java:2826) at net.sf.json.util.JSONUtils.hashCode(JSONUtils.java:221) at net.sf.json.JSONArray.hashCode(JSONArray.java:2022) at net.sf.json.util.JSONUtils.hashCode(JSONUtils.java:219) at net.sf.json.JSONArray.hashCode(JSONArray.java:2022) at java.util.HashMap.put(HashMap.java:372)
原因是内存不够,而内存不够的原因真的是恶心死我了。。劳资改了一次又一次,try catch或者一个变量都不敢随便写在循环里,但是无论怎么改都会在第三个州的72000条这里报错。。。
后来意外了解到,很有可能是createCell这行代码出的问题,写每一个cell的时候都是似乎都是新写出来的。。这个为啥没有回收我也不是特别清楚,不知道是不是有对应的销毁这种对象的方法。。但是爸爸不想找了。。。
换了一种存法,存成csv格式,代码贴上:
BufferedWriter writer = null;
File file = new File("dataFiles/"+state+".csv");
if(!file.exists()) {
file.createNewFile();
}
FileWriter fw = new FileWriter(file);
writer = new BufferedWriter(fw);
for(int s=0;s<jsonArray.size();s++) {
JSONObject jsonObject = jsonArray.getJSONObject(s);
JSONObject attributes = null;
if(jsonObject != null){
attributes = jsonObject.getJSONObject("attributes");
}
if(attributes == null){
continue;
}
Iterator<?> attributesKeys = attributes.keySet().iterator();
while (attributesKeys.hasNext()) {
String key = (String) attributesKeys.next();
String value = format(attributes.getString(key)));
writer.write(value+", ");
}
writer.write(""+", ");
writer.write(""+", ");
writer.write(state+", ");
writer.newLine();
}
writer.close(); //一定不能忘记写
劳资以后要是再存xlsx格式劳资就是狗!!
写这个代码值得一提的是两个命令,这里直接copy下来
javac -cp /store/SaveExcel/poi-ooxml-schemas-3.7-20101029.jar:/storeutils/SaveExcel/json-lib-2.3-jdk15.jar:/store/data/code/readers/utils/SaveExcel/poi-3.7-20101029.jar:/store/SaveExcel/poi-ooxml-3.7-20101029.jar:/store/data/code/readers/utils/SaveExcel/xmlbeans-3.1.0.jar:/store/SaveExcel/poi-examples-3.7-20101029.jar:/sto/SaveExcel/poi-scratchpad-3.7-20101029.jar:/store/data/code/readers/utils/SaveExcel/dom4j-1.6.1.jar:/store/SaveExcel/commons-beanutils-1.8.3.jar:/store/data/code/readers/utils/SaveExcel/commons-collections-3.2.jar:/store/SaveExcel/commons-lang-2.4.jar:/store/data/code/readers/utils/SaveExcel/commons-logging.jar:/store/data/SaveExcel/ezmorph-1.0.5.jar:. SaveToExcel.java
这个jar包位置对应关系一定不要错了。。编译完之后会生成class文件,这个class文件可以后台跑,对应的命令:
nohup java -Xmx2048m -cp /store/data/code/readers/utils/SaveExcel/poi-ooxml-schemas-3.7-20101029.jar:/store/data/code/readers/utils/SaveExcel/json-lib-2.3-jdk15.jar:/store/data/code/readers/utils/SaveExcel/poi-3.7-20101029.jar:/store/data/code/readers/utils/SaveExcel/poi-ooxml-3.7-20101029.jar:/store/data/code/readers/utils/SaveExcel/xmlbeans-3.1.0.jar:/store/data/code/readers/utils/SaveExcel/poi-examples-3.7-20101029.jar:/store/data/code/readers/utils/SaveExcel/poi-scratchpad-3.7-20101029.jar:/store/data/code/readers/utils/SaveExcel/dom4j-1.6.1.jar:/store/data/code/readers/utils/SaveExcel/commons-beanutils-1.8.3.jar:/store/data/code/readers/utils/SaveExcel/commons-collections-3.2.jar:/store/data/code/readers/utils/SaveExcel/commons-lang-2.4.jar:/store/data/code/readers/utils/SaveExcel/commons-logging.jar:/store/data/code/readers/utils/SaveExcel/ezmorph-1.0.5.jar:. SaveToExcel &
nohup会生成一个文件,里面会有运行时的输出信息,或者报错的错误信息,如果你准备重新跑的时候记得删掉这个文件,不然会追加的。。Xmx2048m表示给的内存,给了两个G,最开始我以为错误是这个数据给小了,但是数据组说,几十万条数据也就才几十兆,所以否决了这个想法。。。结尾的&表示在后台跑。。
还有一个查看的命令,如果代码有问题,但是没有报错,这种情况找出pid,并kill掉,但是这个pid一定不要找错了。。
32599应该是pid,但是这个好像经常变,所以我不太确定。。kill的时候一定要稍稍慎重一点,因为可能会影响其他的
纪念一下因为这个破东西两个加班的晚上。。。