最近想将数据保存到Excel文件中,一件很简单的事情,结果遇到了坑。。。
最新的Excel文件操作会原来的数据给覆盖掉!!囧了个囧,这种坑我也不想的
示例代码
关于示例代码网上其实有很多,遍历和写入都有,其实很简单,当时直接就拿来用了。
我就参考的这个https://www.cnblogs.com/wangyang108/p/6030420.html
下面是一段写Excel表格的方法:
public static void main(String[] args) throws IOException
{
// 创建工作薄
HSSFWorkbook workbook = new HSSFWorkbook();
// 创建工作表
HSSFSheet sheet = workbook.createSheet("sheet1");
for (int row = 0; row < 10; row++)
{
HSSFRow rows = sheet.createRow(row);
for (int col = 0; col < 10; col++)
{
// 向工作表中添加数据
rows.createCell(col).setCellValue("data" + row + col);
}
}
File xlsFile = new File("poi.xls");
FileOutputStream xlsStream = new FileOutputStream(xlsFile);
workbook.write(xlsStream);
}
出现的问题
最开始的时候拿来用测试是没有问题的,结果跑了一阵以后发现以前的数据没有了,定位下来是多次对同一Excel文件进行写的操作时数据覆盖了。
人懒,在网上找了一下,发现有人和我问题差不多,有人给的建议是在新建文件流时,在后面加一个append = true,表示追加,如下。听起来像那么一回事,我也就信了。
FileOutputStream xlsStream = new FileOutputStream(xlsFile,true);
然并卵额
问题分析
事实证明,脑子这东西,还是能用就用,不然会退化哟呵…
这个问题在于每次我每次创建的与Excel对应的HSSFWorkbook都是完全空白的,然后在此基础上进行的后续一系列修改操作。之后的保存,当然会将原来的覆盖。
HSSFWorkbook workbook = new HSSFWorkbook();
我不知道目的文件原来是什么状况,我又怎么知道该如何对它进行修改呢?毕竟这又不是规定死了固定内容对应固定位置,那样才能直接将data写进去。
所以,在写之前,还必须有载入原有文件这一操作。如下:
workbook = new HSSFWorkbook();
file = new File(fileName);
try {
in = new FileInputStream(file);
workbook = new HSSFWorkbook(in);
in.close();
out = new FileOutputStream(file);
return true;
} catch (FileNotFoundException e) {
printf("%s :目的文件没有找到!新建一个\n",fileName);
return createNewExcel(fileName);
} catch (IOException e) {
e.printStackTrace();
return false;
}
思路与代码实现
或者,我们可以参考平时我们使用Excel表格的情况,来整理一下思路。
假设我们有一个Excel表格,对它进行操作的步骤应该是这样:
- 打开/新建表格
- 对表格进行读/写
- (保存) ()表示可省略跳过,譬如保存操作可以放到最后统一进行
- 对表格进行读/写
- (保存)
- …
- 对表格进行读/写
- (保存)
- 关闭表格
根据这个思路,整体代码如下
package nicelee.utils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
public class ExcelHelper extends Log{
HSSFWorkbook workbook = null;
//HSSFSheet sheet = null;
File file = null;
FileOutputStream out = null;
FileInputStream in = null;
/***
* 新建Excel
* @param fileName
* @return 创建结果
*/
public boolean createNewExcel(String fileName){
workbook = new HSSFWorkbook();
file = new File(fileName);
try {
out = new FileOutputStream(file);
workbook.write(out);
return true;
} catch (FileNotFoundException e) {
printf("%s :目的文件没有找到!\n",fileName);
return false;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
/**
* 打开Excel,并读取全部内容缓存至 workbook
* @param fileName
* @return 读取结果
*/
public boolean openExcel(String fileName){
workbook = new HSSFWorkbook();
file = new File(fileName);
try {
in = new FileInputStream(file);
workbook = new HSSFWorkbook(in);
in.close();
out = new FileOutputStream(file);
return true;
} catch (FileNotFoundException e) {
printf("%s :目的文件没有找到!新建一个\n",fileName);
return createNewExcel(fileName);
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
/**
* 关闭Excel文件,这个是必须操作
*/
public void closeExcel(){
try {
workbook.write(out);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取指定位置的值
* @param sheet
* @param row
* @param col
* @return
*/
@SuppressWarnings("deprecation")
private String getCellValue(HSSFSheet sheet,int row,int col){
HSSFCell cell = getCell(sheet,row,col);
return cell.getStringCellValue();
}
/**
* 获取指定位置的值
* @param sheetName
* @param row
* @param col
* @return
*/
public String getCellValue(String sheetName,int row,int col){
HSSFSheet sheet = getSheet(sheetName);
return getCellValue(sheet, row, col);
}
/**
* 写入指定值
* @param sheet
* @param row
* @param col
* @param value
* @param isSaveNow(是否马上保存)
*/
public void setCellValue(String sheetName,int row,int col, String value, boolean isSaveNow){
HSSFSheet sheet = workbook.getSheet(sheetName);
setCellValue(sheet, row, col, value, isSaveNow);
}
/**
* 写入指定值
* @param sheet
* @param row
* @param col
* @param value
* 默认在文件关闭时保存
*/
public void setCellValue(String sheetName,int row,int col, String value){
HSSFSheet sheet = getSheet(sheetName);
boolean isSaveNow =false;
setCellValue(sheet, row, col, value, isSaveNow);
}
/**
* 写入指定值
* @param sheet
* @param row
* @param col
* @param value
* @param isSaveNow(是否马上保存)
*/
@SuppressWarnings("deprecation")
private void setCellValue(HSSFSheet sheet,int row,int col, String value, boolean isSaveNow){
HSSFCell cell = getCell(sheet,row,col);
cell.setCellValue(value);
if(isSaveNow){
try {
workbook.write(out);
} catch (IOException e) {
e.printStackTrace();
}
}
}
HSSFSheet getSheet(String sheetName){
HSSFSheet sheet = workbook.getSheet(sheetName);
if(sheet == null){
sheet = workbook.createSheet(sheetName);
printf("Sheet - %s创建\n",sheetName);
}
return sheet;
}
HSSFCell getCell(HSSFSheet sheet,int row,int col){
HSSFRow rows = sheet.getRow(row);
if( rows == null ){
rows = sheet.createRow(row);
printf("第%d行创建\n",row);
}
HSSFCell cell = rows.getCell(col);
if( cell == null ){
cell = rows.createCell(col);
printf("第%d行,第%d列创建\n",row,col);
}
return cell;
}
}