在maven项目中,首先需要引入以下几个jar包,需要注意的是版本号一定要统一:
<!-- poi解析excel文件 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.12</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.12</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-excelant</artifactId>
<version>3.12</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>3.12</version>
</dependency>
下面贴出关键poi读取excel文件的关键代码:
/**
*
* @描述:根据文件名读取excel文件
*
*/
public Map<String, Object> read(MultipartFile file) throws Exception {
InputStream is = null;
String filePath = file.getOriginalFilename();
Map<String, Object> map;
try {
/** 判断文件的类型,是2003还是2007 */
boolean isExcel2003 = true;
if (isExcel2007(filePath)) {
isExcel2003 = false;
}
/** 调用本类提供的根据流读取的方法 */
is = file.getInputStream();
map = read(is, isExcel2003);
is.close();
} catch (Exception ex) {
logger.error(ex.getMessage(), ex);
throw new Exception("读取Excel文件出错!");
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
is = null;
logger.error(e.getMessage(), e);
}
}
}
/** 返回最后读取的结果 */
return map;
}
判断Excel文件的类型是哪个版本:
/**
*
* @描述:是否是2003的excel,返回true是2003
*
* @返回值:boolean
*/
public static boolean isExcel2003(String filePath) {
return filePath.matches("^.+\\.(?i)(xls)$");
}
/**
*
* @描述:是否是2007的excel,返回true是2007
*
* @返回值:boolean
*/
public static boolean isExcel2007(String filePath) {
return filePath.matches("^.+\\.(?i)(xlsx)$");
}
根据文件流来进行文件的读取:
/**
*
* @描述:根据流读取Excel文件
*
*/
public Map<String, Object> read(InputStream inputStream, boolean isExcel2003) throws Exception {
try {
/** 根据版本选择创建Workbook的方式 */
Workbook wb = null;
if (isExcel2003) {
wb = new HSSFWorkbook(inputStream);
} else {
wb = new XSSFWorkbook(inputStream);
}
return read(wb);
} catch (IOException e) {
logger.error(e.getMessage(), e);
throw new Exception("读取Excel文件出错!");
}
}
/**
* 读取excel文件内容,默认读取第一列的数据
*
* @描述:读取第一列数据
*/
private Map<String, Object> read(Workbook wb) {
int totalRows = 0;// 总行数
Map<String, Object> map = new HashMap<String, Object>();
try {
String data = new String();
/** 得到第一个shell */
Sheet sheet = wb.getSheetAt(0);//得到Excel文件中的第一个工作簿
/** 得到Excel的总行数 */
totalRows = sheet.getPhysicalNumberOfRows();
for (int r = 0; r < totalRows; r++) {//遍历文件
Row row = sheet.getRow(r);//得到工作簿中的指定行
if (row == null) {
continue;
}
Cell cell = row.getCell(0);//getCell(0)代表获得第一列
String cellValue = "";
if (null != cell) {
// 以下是判断数据的类型
switch (cell.getCellType()) {
case HSSFCell.CELL_TYPE_NUMERIC: // 数字
cellValue = cell.getNumericCellValue() + "";
break;
case HSSFCell.CELL_TYPE_STRING: // 字符串
cellValue = cell.getStringCellValue();
break;
case HSSFCell.CELL_TYPE_BOOLEAN: // Boolean
cellValue = cell.getBooleanCellValue() + "";
break;
case HSSFCell.CELL_TYPE_FORMULA: // 公式
cellValue = cell.getCellFormula() + "";
break;
case HSSFCell.CELL_TYPE_BLANK: // 空值
cellValue = "";
break;
case HSSFCell.CELL_TYPE_ERROR: // 故障
cellValue = "非法字符";
break;
default:
cellValue = "未知类型";
break;
}
}
/** 保存第r行的数据 */
data = cellValue;
map.put("data",data);
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return map;
下面通过poi将数据写入到excel文件当中,一下写入文件,是可以生成批量的Excel文件,根据数据库中查到的数据,分成1w数据一个Excel文件:
/**
*
* @param param
* @param port
* @param upTime
* @return
*/
private void getExcelData() {
Connection conn = null;
PreparedStatement pStatement = null;
ResultSet resultSet = null;
Workbook wb = null;
Sheet sheet = null;
String[] title = { "手机号码", "操作类型", "生效时间", "失效时间" };
try {
conn = dataSource.getConnection();
int total = 19998;// 导出数据的数量
int yu = total % 10000;
int num = total / 10000;
String s = "select * from mobile";
if (yu > 0)
num += 1;
for (int i = 1; i <= num; i++) {
int begin = 0;
File f = new File(excelPath + fileName + "_" + i + ".xlsx");//创建excel文件
wb = new XSSFWorkbook();
sheet = wb.createSheet("Sheet1");//创建excel文件的第一个工作簿叫Sheet1
// DataFormat format=wb.createDataFormat();//用于设置日期格式
Row row = sheet.createRow(0);//创建第一行
row.setHeight((short) 500);//设置行高
Cell cell = row.createCell(0);//创建第一列
// CellStyle style = wb.createCellStyle();// 样式对象
// style.setFillForegroundColor(HSSFColor.PALE_BLUE.index);//颜色
// style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);//垂直居中
// style.setAlignment(CellStyle.ALIGN_CENTER);//水平居中
// style.setDataFormat(format.getFormat("yyyy/m/d"));//设置制定的日期格式
// style.setWrapText(true);// 显示不下时自动换行
CellStyle style=wb.createCellStyle();
DataFormat fmat=wb.createDataFormat();
style.setDataFormat(fmat.getFormat("yyyy/m/d"));
cell.setCellStyle(style);
for (int j = 0; j < title.length; j++) {//设置excel的表头
cell = row.createCell(j);
cell.setCellValue(title[j]);
if(j==0)
cell.setCellType(HSSFCell.CELL_TYPE_STRING);
if(j==2||j==3) {
cell.setCellStyle(style);
}
sheet.setColumnWidth(j, 20 * 256);
}
pStatement = conn.prepareStatement(s);
resultSet = pStatement.executeQuery();
int index = 0;
while (resultSet.next()) {
String mobile = resultSet.getString("mobile");
row = (Row) sheet.createRow(index + 1);//循环创建每一行的对象,进行存放数据
row.setHeight((short) 500);
Cell c0=row.createCell(0);//第一列
c0.setCellType(HSSFCell.CELL_TYPE_STRING);
c0.setCellValue(mobile);//放入数据
row.createCell(1).setCellValue(type);//创建第二列并放入数据
Cell c2=row.createCell(2);//创建第三列
c2.setCellStyle(style);
c2.setCellValue(forceTime);
Cell c3=row.createCell(3);//创建第四列
c3.setCellStyle(style);
c3.setCellValue("2110/2/2");
index++;
}
//文件写入流到Excel文件
OutputStream outputStream = new FileOutputStream(excelPath + fileName + "_" + i + ".xlsx");
wb.write(outputStream);
outputStream.flush();
outputStream.close();
begin += 10000;
}
} catch (SQLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
JdbcUtil.closeResultSet(resultSet);
JdbcUtil.closeStatement(pStatement);
JdbcUtil.closeConnection(conn);
}
}
使用poi进行对Excel文件进行操作时,可以将Excel想像成一个二维数组,像操作二维数组一样进行操作,这样就感觉简便很多。
以上代码读取超大文件的Excel,会出现速度过慢的情况,如果各位有更好的读取超大文件的Excel的方法,欢迎留言。