600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > java poi写入excel_Java使用POI读取和写入Excel指南

java poi写入excel_Java使用POI读取和写入Excel指南

时间:2021-10-26 01:04:09

相关推荐

java poi写入excel_Java使用POI读取和写入Excel指南

做项目时经常有通过程序读取Excel数据,或是创建新的Excel并写入数据的需求;

网上很多经验教程里使用的POI版本都比较老了,一些API在新版里已经废弃,这里基于最新的Apache POI 4.0.1版本来总结一下整个读取和写入Excel的过程,希望能帮助到需要的人 ^_^

1. 准备工作

1.1 在项目中引入Apache POI相关类库

引入 Apache POI 和 Apache POI-OOXML 这两个类库,Maven坐标如下:

org.apache.poi

poi

4.0.1

org.apache.poi

poi-ooxml

4.0.1

2. 读取或写入Excel数据

2.1 示例程序结构说明

简单说明一下示例程序的整体结构:ExcelReader.java是实现读取Excel数据功能的类;

ExcelWriter.java是创建新的Excel并向其中写入数据的类;

ExcelDataVO.java封装了读取或写入时每一“行”的数据;

MainTest.java是示例程序的入口类,其中演示了读取和写入Excel数据的整个过程;

2.2 读取数据

示例程序需要从桌面读取 readExample.xlsx 内的数据,readExample.xlsx 的内容如下:

读取Excel时主要调用ExcelReader.java类来读取和解析Excel的具体内容,这里以读取系统文件的形式演示读取过程:(兼容 xls 和 xlsx)

2.2.1 主程序入口类代码:/**

*Author:Dreamer-1

*Date:-03-01

*Time:10:13

*Description:示例程序入口类

*/publicclassMainTest{publicstaticvoidmain(String[]args){//设定Excel文件所在路径

StringexcelFileName="/Users/Dreamer-1/Desktop/myBlog/java解析Excel/readExample.xlsx";//读取Excel文件内容

ListreadResult=ExcelReader.readExcel(excelFileName);

//todo进行业务操作

}

}

读取和写入时封装每一“行”数据的ExcelDataVO.java代码如下:/**

*Author:Dreamer-1

*Date:-03-01

*Time:11:33

*Description:读取Excel时,封装读取的每一行的数据

*/publicclassExcelDataVO{/**

*姓名

*/

privateStringname;/**

*年龄

*/

privateIntegerage;/**

*居住地

*/

privateStringlocation;/**

*职业

*/

privateStringjob;publicStringgetName(){returnname;

}publicvoidsetName(Stringname){this.name=name;

}publicIntegergetAge(){returnage;

}publicvoidsetAge(Integerage){this.age=age;

}publicStringgetLocation(){returnlocation;

}publicvoidsetLocation(Stringlocation){this.location=location;

}publicStringgetJob(){returnjob;

}publicvoidsetJob(Stringjob){this.job=job;

}

}

2.2.2 Excel解析类的代码:/**

*Author:Dreamer-1

*Date:-03-01

*Time:10:21

*Description:读取Excel内容

*/publicclassExcelReader{privatestaticLoggerlogger=Logger.getLogger(ExcelReader.class.getName());//日志打印类

privatestaticfinalStringXLS="xls";privatestaticfinalStringXLSX="xlsx";/**

*根据文件后缀名类型获取对应的工作簿对象

*@paraminputStream读取文件的输入流

*@paramfileType文件后缀名类型(xls或xlsx)

*@return包含文件数据的工作簿对象

*@throwsIOException

*/

publicstaticWorkbookgetWorkbook(InputStreaminputStream,StringfileType)throwsIOException{

Workbookworkbook=null;if(fileType.equalsIgnoreCase(XLS)){

workbook=newHSSFWorkbook(inputStream);

}elseif(fileType.equalsIgnoreCase(XLSX)){

workbook=newXSSFWorkbook(inputStream);

}returnworkbook;

}/**

*读取Excel文件内容

*@paramfileName要读取的Excel文件所在路径

*@return读取结果列表,读取失败时返回null

*/

publicstaticListreadExcel(StringfileName){

Workbookworkbook=null;

FileInputStreaminputStream=null;try{//获取Excel后缀名

StringfileType=fileName.substring(fileName.lastIndexOf(".")+1,fileName.length());//获取Excel文件

FileexcelFile=newFile(fileName);if(!excelFile.exists()){

logger.warning("指定的Excel文件不存在!");returnnull;

}//获取Excel工作簿

inputStream=newFileInputStream(excelFile);

workbook=getWorkbook(inputStream,fileType);//读取excel中的数据

ListresultDataList=parseExcel(workbook);returnresultDataList;

}catch(Exceptione){

logger.warning("解析Excel失败,文件名:"+fileName+"错误信息:"+e.getMessage());returnnull;

}finally{try{if(null!=workbook){

workbook.close();

}if(null!=inputStream){

inputStream.close();

}

}catch(Exceptione){

logger.warning("关闭数据流出错!错误信息:"+e.getMessage());returnnull;

}

}

}/**

*解析Excel数据

*@paramworkbookExcel工作簿对象

*@return解析结果

*/

privatestaticListparseExcel(Workbookworkbook){

ListresultDataList=newArrayList<>();//解析sheet

for(intsheetNum=0;sheetNum

Sheetsheet=workbook.getSheetAt(sheetNum);//校验sheet是否合法

if(sheet==null){continue;

}//获取第一行数据

intfirstRowNum=sheet.getFirstRowNum();

RowfirstRow=sheet.getRow(firstRowNum);if(null==firstRow){

logger.warning("解析Excel失败,在第一行没有读取到任何数据!");

}//解析每一行的数据,构造数据对象

introwStart=firstRowNum+1;introwEnd=sheet.getPhysicalNumberOfRows();for(introwNum=rowStart;rowNum

Rowrow=sheet.getRow(rowNum);if(null==row){continue;

}

ExcelDataVOresultData=convertRowToData(row);if(null==resultData){

logger.warning("第"+row.getRowNum()+"行数据不合法,已忽略!");continue;

}

resultDataList.add(resultData);

}

}returnresultDataList;

}/**

*将单元格内容转换为字符串

*@paramcell

*@return

*/

privatestaticStringconvertCellValueToString(Cellcell){if(cell==null){returnnull;

}

StringreturnValue=null;switch(cell.getCellType()){caseNUMERIC://数字

DoubledoubleValue=cell.getNumericCellValue();//格式化科学计数法,取一位整数

DecimalFormatdf=newDecimalFormat("0");

returnValue=df.format(doubleValue);break;caseSTRING://字符串

returnValue=cell.getStringCellValue();break;caseBOOLEAN://布尔

BooleanbooleanValue=cell.getBooleanCellValue();

returnValue=booleanValue.toString();break;caseBLANK://空值

break;caseFORMULA://公式

returnValue=cell.getCellFormula();break;caseERROR://故障

break;default:break;

}returnreturnValue;

}/**

*提取每一行中需要的数据,构造成为一个结果数据对象

*

*当该行中有单元格的数据为空或不合法时,忽略该行的数据

*

*@paramrow行数据

*@return解析后的行数据对象,行数据错误时返回null

*/

privatestaticExcelDataVOconvertRowToData(Rowrow){

ExcelDataVOresultData=newExcelDataVO();

Cellcell;intcellNum=0;//获取姓名

cell=row.getCell(cellNum++);

Stringname=convertCellValueToString(cell);

resultData.setName(name);//获取年龄

cell=row.getCell(cellNum++);

StringageStr=convertCellValueToString(cell);if(null==ageStr||"".equals(ageStr)){//年龄为空

resultData.setAge(null);

}else{

resultData.setAge(Integer.parseInt(ageStr));

}//获取居住地

cell=row.getCell(cellNum++);

Stringlocation=convertCellValueToString(cell);

resultData.setLocation(location);//获取职业

cell=row.getCell(cellNum++);

Stringjob=convertCellValueToString(cell);

resultData.setJob(job);returnresultData;

}

}

2.2.3 应用场景补充

一般我们会有这样的应用场景,即:在前台页面的文件上传入口上传本地的Excel文件到后台,后台收到Excel文件后进行解析并做对应的业务操作;

这里假设前台已经有了上传文件的入口,再简单贴一下后台的解析代码;

后台接收前台数据的Controller层代码示例:@PostMapping("/uploadExcel")publicResponseEntity>uploadImage(MultipartFilefile){//检查前台数据合法性

if(null==file||file.isEmpty()){

logger.warning("上传的Excel商品数据文件为空!上传时间:"+newDate());returnnewResponseEntity<>(HttpStatus.BAD_REQUEST);

}try{//解析Excel

ListparsedResult=ExcelReader.readExcel(file);//todo进行业务操作

returnnewResponseEntity<>(HttpStatus.OK);

}catch(Exceptione){

logger.warning("上传的Excel商品数据文件为空!上传时间:"+newDate());returnnewResponseEntity<>(HttpStatus.BAD_REQUEST);

}

}

ExcelReader.java中的 readExcel() 方法需要做一定的修改,代码如下:/**

*读取Excel文件内容

*@paramfile上传的Excel文件

*@return读取结果列表,读取失败时返回null

*/

publicstaticListreadExcel(MultipartFilefile){

Workbookworkbook=null;try{//获取Excel后缀名

StringfileName=file.getOriginalFilename();if(fileName==null||fileName.isEmpty()||fileName.lastIndexOf(".")

logger.warning("解析Excel失败,因为获取到的Excel文件名非法!");returnnull;

}

StringfileType=fileName.substring(fileName.lastIndexOf(".")+1,fileName.length());//获取Excel工作簿

workbook=getWorkbook(file.getInputStream(),fileType);//读取excel中的数据

ListresultDataList=parseExcel(workbook);returnresultDataList;

}catch(Exceptione){

logger.warning("解析Excel失败,文件名:"+file.getOriginalFilename()+"错误信息:"+e.getMessage());returnnull;

}finally{try{if(null!=workbook){

workbook.close();

}

}catch(Exceptione){

logger.warning("关闭数据流出错!错误信息:"+e.getMessage());returnnull;

}

}

}

2.3 写入数据

写入数据时主要调用ExcelWriter.java来创建Excel工作簿对象并写入数据,这里以写入系统文件数据为例演示写入的过程:

2.3.1 主程序入口类代码/**

*Author:Dreamer-1

*Date:-03-01

*Time:10:13

*Description:示例程序入口类

*/publicclassMainTest{privatestaticLoggerlogger=Logger.getLogger(MainTest.class.getName());publicstaticvoidmain(String[]args){//创建需要写入的数据列表

ListdataVOList=newArrayList<>(2);

ExcelDataVOdataVO=newExcelDataVO();

dataVO.setName("小明");

dataVO.setAge(18);

dataVO.setLocation("广州");

dataVO.setJob("大学生");

ExcelDataVOdataVO2=newExcelDataVO();

dataVO2.setName("小花");

dataVO2.setAge(19);

dataVO2.setLocation("深圳");

dataVO2.setJob("大学生");

dataVOList.add(dataVO);

dataVOList.add(dataVO2);//写入数据到工作簿对象内

Workbookworkbook=ExcelWriter.exportData(dataVOList);//以文件的形式输出工作簿对象

FileOutputStreamfileOut=null;try{

StringexportFilePath="/Users/Dreamer-1/Desktop/myBlog/java解析Excel/writeExample.xlsx";

FileexportFile=newFile(exportFilePath);if(!exportFile.exists()){

exportFile.createNewFile();

}

fileOut=newFileOutputStream(exportFilePath);

workbook.write(fileOut);

fileOut.flush();

}catch(Exceptione){

logger.warning("输出Excel时发生错误,错误原因:"+e.getMessage());

}finally{try{if(null!=fileOut){

fileOut.close();

}if(null!=workbook){

workbook.close();

}

}catch(IOExceptione){

logger.warning("关闭输出流时发生错误,错误原因:"+e.getMessage());

}

}

}

}

2.3.2 写入Excel类的代码

ExcelWriter.java类中,你可以根据实际需要替换 CELL_HEADS 列头的信息,然后重写 convertDataToRow 方法,转换你自己的行数据;/**

*Author:Dreamer-1

*Date:-03-01

*Time:11:09

*Description:生成Excel并写入数据

*/publicclassExcelWriter{privatestaticListCELL_HEADS;//列头

static{//类装载时就载入指定好的列头信息,如有需要,可以考虑做成动态生成的列头

CELL_HEADS=newArrayList<>();

CELL_HEADS.add("姓名");

CELL_HEADS.add("年龄");

CELL_HEADS.add("居住城市");

CELL_HEADS.add("职业");

}/**

*生成Excel并写入数据信息

*@paramdataList数据列表

*@return写入数据后的工作簿对象

*/

publicstaticWorkbookexportData(ListdataList){//生成xlsx的Excel

Workbookworkbook=newSXSSFWorkbook();//如需生成xls的Excel,请使用下面的工作簿对象,注意后续输出时文件后缀名也需更改为xls

//Workbookworkbook=newHSSFWorkbook();

//生成Sheet表,写入第一行的列头

Sheetsheet=buildDataSheet(workbook);//构建每行的数据内容

introwNum=1;for(Iteratorit=dataList.iterator();it.hasNext();){

ExcelDataVOdata=it.next();if(data==null){continue;

}//输出行数据

Rowrow=sheet.createRow(rowNum++);

convertDataToRow(data,row);

}returnworkbook;

}/**

*生成sheet表,并写入第一行数据(列头)

*@paramworkbook工作簿对象

*@return已经写入列头的Sheet

*/

privatestaticSheetbuildDataSheet(Workbookworkbook){

Sheetsheet=workbook.createSheet();//设置列头宽度

for(inti=0;i

sheet.setColumnWidth(i,4000);

}//设置默认行高

sheet.setDefaultRowHeight((short)400);//构建头单元格样式

CellStylecellStyle=buildHeadCellStyle(sheet.getWorkbook());//写入第一行各列的数据

Rowhead=sheet.createRow(0);for(inti=0;i

Cellcell=head.createCell(i);

cell.setCellValue(CELL_HEADS.get(i));

cell.setCellStyle(cellStyle);

}returnsheet;

}/**

*设置第一行列头的样式

*@paramworkbook工作簿对象

*@return单元格样式对象

*/

privatestaticCellStylebuildHeadCellStyle(Workbookworkbook){

CellStylestyle=workbook.createCellStyle();//对齐方式设置

style.setAlignment(HorizontalAlignment.CENTER);//边框颜色和宽度设置

style.setBorderBottom(BorderStyle.THIN);

style.setBottomBorderColor(IndexedColors.BLACK.getIndex());//下边框

style.setBorderLeft(BorderStyle.THIN);

style.setLeftBorderColor(IndexedColors.BLACK.getIndex());//左边框

style.setBorderRight(BorderStyle.THIN);

style.setRightBorderColor(IndexedColors.BLACK.getIndex());//右边框

style.setBorderTop(BorderStyle.THIN);

style.setTopBorderColor(IndexedColors.BLACK.getIndex());//上边框

//设置背景颜色

style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());

style.setFillPattern(FillPatternType.SOLID_FOREGROUND);//粗体字设置

Fontfont=workbook.createFont();

font.setBold(true);

style.setFont(font);returnstyle;

}/**

*将数据转换成行

*@paramdata源数据

*@paramrow行对象

*@return

*/

privatestaticvoidconvertDataToRow(ExcelDataVOdata,Rowrow){intcellNum=0;

Cellcell;//姓名

cell=row.createCell(cellNum++);

cell.setCellValue(null==data.getName()?"":data.getName());//年龄

cell=row.createCell(cellNum++);if(null!=data.getAge()){

cell.setCellValue(data.getAge());

}else{

cell.setCellValue("");

}//所在城市

cell=row.createCell(cellNum++);

cell.setCellValue(null==data.getLocation()?"":data.getLocation());//职业

cell=row.createCell(cellNum++);

cell.setCellValue(null==data.getJob()?"":data.getJob());

}

}

示例程序运行后将会在指定的系统路径下生成 writeExample.xlsx文件,其内容如下:

2.3.3 应用场景补充

一般写入Excel时会有这样的场景:前台页面上有一个导出按钮,点击后将后台某张表里的数据以Excel的形式导出,导出的Excel文件通过浏览器下载到用户系统中;

这里默认前台页面已经有相应的按钮功能,给出对应的Controller层代码供参考:@GetMapping("/exportExcel")publicvoidexportExcel(HttpServletRequestrequest,HttpServletResponseresponse){

Workbookworkbook=null;

OutputStreamout=null;try{//todo根据业务需求获取需要写入Excel的数据列表dataList

//生成Excel工作簿对象并写入数据

workbook=ExcelWriter.exportData(dataList);//写入Excel文件到前端

if(null!=workbook){

StringexcelName="示例Excel导出";

StringfileName=excelName+DateUtil.format(newDate(),DateUtil.SHORT_DATE)+".xlsx";

fileName=newString(fileName.getBytes("UTF-8"),"iso8859-1");

response.setHeader("Content-Disposition","attachment;filename="+fileName);

response.setContentType("application/x-download");

response.setCharacterEncoding("UTF-8");

response.addHeader("Pargam","no-cache");

response.addHeader("Cache-Control","no-cache");

response.flushBuffer();

out=response.getOutputStream();

workbook.write(out);

out.flush();

}

}catch(Exceptione){

logger.WARNING("写入Excel过程出错!错误原因:"+e.getMessage());

}finally{try{if(null!=workbook){

workbook.close();

}if(null!=out){

out.close();

}

}catch(IOExceptione){

logger.WARNING("关闭workbook或outputStream出错!");

}

}

}//前台页面发送请求到后台Controller时的JS代码可参考:varurl="/exportExcel";

window.location=url;

3. 源码下载

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。