06月12, 2014

XSSF追加写excel

由于工作需要,经常会对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();
        }        
    }

本文链接:http://blogs.360.cn/post/xssf追加写excel.html

-- EOF --

Comments