之前一直用jxl处理excel文件,但是jxl不能处理xlsx文件,局限性太大。最近开始尝试使用poi。
读取表格数据,或者创建新表格的教程如下:
http://www.yiibai.com/apache_poi/apache_poi_spreadsheets.html
实际运用中,有时需要在已有的Excel表格中写入数据。
具体代码如下:
Poi工具类如下:
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.*;
import java.math.BigDecimal;
import java.util.*;
/**
* Util提供的所有静态方法返回的对象都是Workbook,可根据需求再做处理
*
*/
public class PoiUtil {
public static final int EXCEL_2003 = 2003;
public static final int EXCEL_2007 = 2007;
private PoiUtil() {
}
/**
* 根据文件名,判断版本号,获取Excel poi对象
*
* @param fileName
* @param in
* @return
* @throws IOException
*/
public static Workbook getWorkbook(InputStream in, String fileName ) throws IOException {
if (in == null) {
return null;
}
int edition = getEdition(fileName);
if (edition == EXCEL_2003) {
return new HSSFWorkbook(in);
} else if (edition == EXCEL_2007) {
return new XSSFWorkbook(in);
}
return null;
}
/*
* 判断excel文件是2003版的xls文件,还是xlsx文件
* @param fileName
* @return
*/
public static int getEdition(String fileName){
int edition;
if (StringUtils.isEmpty(fileName)) {
return 0;
}
String xlsxFile=fileName.substring(fileName.length()-4);
String xlsFile=fileName.substring(fileName.length()-3);
if( xlsxFile.equals("xlsx") ){
edition= EXCEL_2007;
}else if(xlsFile.equals("xls")) {
edition= EXCEL_2003;
}else {
edition=0;
}
return edition;
}
/**
* 获取单元格的String值
* 文本型直接获取,数值型的一般是double类型,日期和数字要分开处理
* @param cell
* @return
*/
public static String getCellString(Cell cell) {
String cellStr="";
if(cell==null) {
return cellStr;
}
switch (cell.getCellType()) {
// 验证每一个单元格的类型
case STRING:
cellStr=cell.getStringCellValue();
if (cellStr.trim().isEmpty()) {
cellStr = "";
}
break;
case NUMERIC:
// if( DateUtil.isCellDateFormatted(cell)) {
// Date date=cell.getDateCellValue();
// cellStr=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
// }else {
// BigDecimal bigDecimal=new BigDecimal(cell.getNumericCellValue());
// cellStr=bigDecimal.toString();
// }
// 表格中返回的数字类型是科学计数法因此不能直接转换成字符串格式
BigDecimal bigDecimal= BigDecimal.valueOf(cell.getNumericCellValue());
cellStr=bigDecimal.toString();
break;
case FORMULA:
cellStr = BigDecimal.valueOf(cell.getNumericCellValue()).toPlainString();
break;
case BOOLEAN:
cellStr = Boolean.toString(cell.getBooleanCellValue());
break;
case BLANK:
cellStr = "";
break;
default:
break;
}
//去掉多余的空格和换行符
return cellStr.trim();
}
/**
* 从指定excel表格中逐行读取数据
*
* @param workbook
* @param startRow 第几行开始读
* @param startCol 第几列开始读
* @param indexSheet 读取excel的哪个工作簿
* @return
*/
public static List<List<String>> getRowColumnList(Workbook workbook, int startRow, int startCol, int indexSheet) {
List<List<String>> rowColumnList = new ArrayList<>();
// 获取指定表对象
Sheet sheet = workbook.getSheetAt(indexSheet);
// 获取最大行数
int rowNum = sheet.getLastRowNum();
for (int i = startRow; i <= rowNum; i++) {
List<String> oneRow = new ArrayList<>();
Row row = sheet.getRow(i);
// 根据当前指针所在行数计算最大列数
int colNum = row.getLastCellNum();
for (int j = startCol; j <= colNum; j++) {
// 确定当前单元格
Cell cell = row.getCell(j);
String cellValue = getCellString(cell);
// 生成一行数据
oneRow.add(cellValue);
}
rowColumnList.add(oneRow);
}
return rowColumnList;
}
/**
* 根据给定的数据直接生成workbook
*
* @param workbook
* @param sheetName
* @param data
* @return
*/
public static Workbook createExcel(Workbook workbook, String sheetName, List<List<String>> data) {
Sheet sheet = workbook.createSheet(sheetName);
for (int i = 0; i < data.size(); i++) {
List<String> oneRow = data.get(i);
Row row = sheet.createRow(i);
for (int j = 0; j < oneRow.size(); j++) {
Cell cell = row.createCell(j);
cell.setCellValue(oneRow.get(j));
}
}
return workbook;
}
/**
* 往指定的sheet表中插入数据,插入的方法是提供一组valueMap。int[]是2维数组代表需要插入的数据坐标,从0开始
*
* @param workbook
* @param sheetIndex
* @param valueMap
* @return
*/
public static Workbook insertExcel(Workbook workbook, int sheetIndex, Map<int[], String> valueMap) {
Sheet sheet = workbook.getSheetAt(sheetIndex);
for (Map.Entry<int[], String> cellEntry : valueMap.entrySet()) {
int x = cellEntry.getKey()[0];
int y = cellEntry.getKey()[1];
String value = cellEntry.getValue();
Row row = sheet.getRow(y);
Cell cell = row.getCell(x);
cell.setCellValue(value);
}
return workbook;
}
/**
* 删除指定行
*
* @param workbook
* @param sheetIndex
* @param rowIndex
* @return
*/
public static Workbook removeRow(Workbook workbook, int sheetIndex, int rowIndex) {
Sheet sheet = workbook.getSheetAt(sheetIndex);
int lastRowNum = sheet.getLastRowNum();
if (rowIndex >= 0 && rowIndex < lastRowNum) {
sheet.shiftRows(rowIndex + 1, lastRowNum, -1);
}
if (rowIndex == lastRowNum) {
sheet.removeRow(sheet.getRow(rowIndex));
}
return workbook;
}
/**
* 将workbook转化为输入流
*
* @param workbook
* @return
*/
public static InputStream workbookConvertorStream(Workbook workbook) {
InputStream in = null;
try {
//临时缓冲区
ByteArrayOutputStream out = new ByteArrayOutputStream();
//创建临时文件
workbook.write(out);
byte[] bookByteAry = out.toByteArray();
int size = bookByteAry.length;
in = new ByteArrayInputStream(bookByteAry);
out.close();
workbook.close();
log.info("workbook文件大小== {}", size);
} catch (Exception e) {
log.error("workbook to inputStream exception catch.", e);
}
return in;
}
/**
* 刷新流的缓存区,将workbook数据写入excel
*
* @param fileName
* @param workbook
* @throws IOException
*/
public static void writeWorkbookToExcel(String fileName, Workbook workbook) throws IOException {
FileOutputStream fos = new FileOutputStream(new File(fileName));
fos.flush();
workbook.write(fos);
//关闭文件流
fos.close();
workbook.close();
}
}
Excel读写的Demo如下:
import com.sf.inc.oewm.util.PoiUtil;
import org.apache.poi.ss.usermodel.*;
import java.io.*;
/**
* Excel读写
* 文件:C:\Users\lenovo\Desktop\ExcelTest.xlsx
*/
public class PoiTest {
public static void main(String[] args) throws Exception {
String input = "C:\\Users\\lenovo\\Desktop\\ExcelTest.xlsx";
// writeExcel(input,2007); //xlsx格式用2007,xls格式用2003
readExcel(input);
}
//读取2003和2007版本的Excel
public static void readExcel(String file) {
try {
//创建文件流
FileInputStream fis = new FileInputStream(new File(file));
//通过接口实例化Workbook工作簿
Workbook workbook = PoiUtil.getWorkbook(fis, file);
//通过接口获得默认的第一个sheet的页面
Sheet sheet = workbook.getSheetAt(0);
//获取sheet页的第一行
Row row1 = sheet.getRow(0);
//从第二行开始读,遍历到最后一行
for (int i = 1; i <= sheet.getLastRowNum(); i++) {
Row row = sheet.getRow(i);//得到每一行
for (int j = 0; j < row.getLastCellNum(); j++) {//得到每一行的每一列
Cell cell = row.getCell(j);
// 根据excel中单元格的属性,来用不同的格式取得有效值
String cellValue = PoiUtil.getCellString(cell);
System.out.println("单元格内容为:" + cellValue);
}
}
fis.close();
workbook.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void writeExcel(String file) throws IOException {
FileInputStream fis = new FileInputStream(new File(file));
Workbook workbook = PoiUtil.getWorkbook(fis,file);
Sheet sheet = workbook.getSheetAt(0);
try {
//获取第一行
Row row0 = sheet.getRow(0);
//在第一行第一列写入数据,类型为string
Cell cell0 = row0.createCell(0, CellType.STRING);
cell0.setCellValue("Order");
//在第二行开始写入数据
for (int i = 1; i <= sheet.getLastRowNum(); i++) {
Row row = sheet.getRow(i);
Cell cell = row.createCell(0, CellType.STRING);
cell.setCellValue(String.valueOf(i + 1));
}
} catch (Exception e) {
e.printStackTrace();
}
fis.close();
writeWorkbookToExcel(fileName, workbook);
}
}
参考博客:
http://www.cnblogs.com/learnhow/p/5538331.html