NiceLeeのBlog 用爱发电 bilibili~

Java poi操作Excel踩坑记录

2018-10-28
nIceLee

阅读:


最近想将数据保存到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(xlsFiletrue);

然并卵额

问题分析

事实证明,脑子这东西,还是能用就用,不然会退化哟呵…
这个问题在于每次我每次创建的与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;
	}
	
	
}


内容
隐藏