由于工作需要,经常会对excel进行读写操作,以前会使用jxl来进行excel的读写,但是它只能处理2000以下版本,经调查之后,最近使用Apache POI XSSF来操作2007版本以上的excel。 当我想要对同一个excel文件进行追加读写的时候,发现一个问题;eclipse编译器没有报错误,但是,在第一次运行程序的时候,会正确写入excel,在接下来,每运行一次,就发现文件大小,增加一倍,但是文件内容,打不开,会提示:“文件已损坏”之类的错误,研究了2个小时,之后,终于发现了问题的原因和解决办法。
我在进行追加写的时候,查了一下JAVA API,发现用于写入数据的输出文件流函数FileOutputStream(String name,boolean append)具有一个boolean类型的append,当第二个参数为true时,则将字节写入文件末尾处,而不是写入文件开始处。顿时很高兴。马上使用了这个函数。下面是我的部分代码。
if(file.exists()) {
fileIn = new FileInputStream(file);
is = fileIn;
//根据输入流创建Workbook对象
wb = (XSSFWorkbook) WorkbookFactory._create_(is);
sh1 = wb.getSheetAt(0);
des=**new** FileOutputStream(savepath,**true**);
}
//进行普遍的创建excel表的操作,然后写入数据
esle{}
但是,当我使用之后,就出现了之前介绍的问题。每运行一次,就发现文件大小,增加一倍,但是文件内容,打不开,会提示:“文件已损坏”之类的错误。然后绞尽脑汁的找了半天,还尝试了利用文件重命名来进行操作,不过都以失败告终;后来,尝试了一次写入多条数据,然后继续操作,发现,文件依旧第一次可以正确写入,大小成倍增加;才想明白,我这个利用FileOutputStream实现的追加写,是每一次,都把excel文件的文件头和文件内容都追加进来了,导致excel的格式错误,才会一直不能正确打开;解决方法,把FileOutputStream的第二个参数,改为false,或者忽略不写,就可以成功的写入文件。修改后的代码为:
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.ss.util.WorkbookUtil;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public void WriteToExcel(Model Class,String savepath) throws Exception
{
File file=new File(savepath);
XSSFWorkbook wb=new XSSFWorkbook();
FileOutputStream des=null;
FileInputStream fileIn = null;
InputStream is = null;
XSSFSheet sh1 = null;
if(file.exists())
{ fileIn = new FileInputStream(file);
is = fileIn;
//根據輸入流創建Workbook對象
wb = (XSSFWorkbook) WorkbookFactory.create(is);
sh1 = wb.getSheetAt(0);
des=new FileOutputStream(savepath,false);
}
else
{
des=this.makeAnExcel(savepath); //返回fileoutputstream对象
wb=this.makeAnWorkbook();//创建对象,写表头
sh1 = wb.getSheetAt(0);
}
int index = sh1.getLastRowNum();
System.out.println("最后一行行号"+index);
XSSFRow contentRow = null;
try{
if(Class!=null)
{ contentRow = sh1.createRow((short) index++);
ArrayList<String> ls = new ArrayList<String>();
ls.add(Class.getmethod1 ());
ls.add(Class.getmethod2 ());
ls.add(Class.getmethod3());
ls.add(Class.getmethod4 ());
for (int i=0;i<ls.size();i++)
{
XSSFCell namecell=contentRow.createCell(i);
namecell.setCellValue(ls.get(i));}
}
des.flush();
wb.write(des);
if (is != null)
{
is.close();
}
des.close();
System.out.println("ok, I have done!");
}
catch(Exception e)
{
e.printStackTrace();
}
}
Comments