项目源码和笔记Apache POI实现Excel导入、导出

文章资讯 2020-06-17 22:38:44

项目源码和笔记Apache POI实现Excel导入、导出

本项目基于SringBoot,做之前先要保证自己的SringBoot项目能跑起来哦!
准备工作
准备数据库:
DROPTABLEIFEXISTS`oitest`;
CREATETABLE`oitest`(
`id`int(11)NOTNULLAUTO_INCREMENT,
`username`varchar(255)CHARACTERSETutf8COLLATEutf8_general_ciNOTNULL,
`assword`varchar(255)CHARACTERSETutf8COLLATEutf8_general_ciNOTNULL,
`birthday`dateNOTNULL,
`sex`int(255)NOTNULLCOMMENT'1:男2:女',
PRIMARYKEY(`id`)USINGBTREE
)ENGINE=InnoDBAUTO_INCREMENT=41CHARACTERSET=utf8COLLATE=utf8_general_ciROW_FORMAT=Comact;INSERTINTO`oitest`VALUES(1,'张三','123456','2020-06-03',1);
INSERTINTO`oitest`VALUES(2,'李四','123456','2020-06-03',2);
INSERTINTO`oitest`VALUES(3,'王五','123456','2020-06-03',1);添加依赖:
<!--oi处理excel-->
<deendency>
<grouId>org.aache.oi<grouId>
<artifactId>oi-ooxml<artifactId>
<version>3.9<version>
<deendency>1.POI实现将数据库数据导出到Excel中
三层架构的写法这里不在多说了。需要用到的工具类:DateUtil
ackagecom.xiexuchun.Utils;imortjava.text.ParseExcetion;
imortjava.text.SimleDateFormat;
imortjava.util.Calendar;
imortjava.util.Date;ublicclassDateUtil{
**
*yyyyMMddhhmmssSSS
*日期对象转字符串
*
ublicstaticStringformatDate(Datedate,Stringformat){
Stringsult="";
SimleDateFormatsdf=newSimleDateFormat(format);
if(date!=null){
sult=sdf.format(date);
}
turnsult;
}

**
*字符串转日期对象
*@aramstr
*@aramformat
*@turn
*@throwsExcetion
*
ublicstaticDateformatString(Stringstr,Stringformat){
if(StringUtil.isEmty(str)){
turnnull;
}
SimleDateFormatsdf=newSimleDateFormat(format);
try{
turnsdf.arse(str);
}catch(ParseExcetione){
e.rintStackTrace();
}
turnnull;
}

ublicstaticStringgetCurntDateStr()throwsExcetion{
Datedate=newDate();
SimleDateFormatsdf=newSimleDateFormat("yyyyMMddHHmmss");
turnsdf.format(date);
}

**
*输入一个月份,2017-01
*输出2017-01-31
*
ublicstaticStringgetDays(Stringstr){
str=dateAddMonth(str,"yyyy-MM",1);2017-01---2017-02
str=str+"-01";2017-02-01
str=dateAddDay(str,"yyyy-MM-dd",-1);2017-01-31
turnstr;
}

**
*算2个时间差几分
*@aramend
*@arambegin
*@turn
*
ublicstaticlongdate_between(Dateend,Datebegin){
*SimleDateFormatdfs=newSimleDateFormat("yyyy-MM-ddHH:mm:ss");
Datebegin=dfs.arse("2004-01-0211:30:24");
Dateend=dfs.arse("2004-01-0211:31:40");*
longbetween=(end.getTime()-begin.getTime())1000;除以1000是为了转换成秒
longmin=between60;
System.out.rintln("差几分"+min);
turnmin;
}

**
*任意格式的日期
*@aramdate1
*@aramdate2
*@turn1比2大返回1相等返回0小于返回-1
*
ublicstaticintcomaTo(Stringdate1,Stringdate2){
turndate1.comaTo(date2);
} **
*任意格式加1天或者加-1天
*@aramdateStr时间字符串2018-05-0512:11
*@aramdateFormat时间格式yyyy-MM-ddHH:mmssSSS
*@aramn加多少天
*
ublicstaticStringdateAddDay(StringdateStr,StringdateFormat,intn){
try{
SimleDateFormatsdf=newSimleDateFormat(dateFormat);
Calendarcd=Calendar.getInstance();
cd.setTime(sdf.arse(dateStr));
cd.add(Calendar.DATE,n);增加一天
cd.add(Calendar.MONTH,n);增加一个月
turnsdf.format(cd.getTime()); }catch(Excetione){
turnnull;
}
}

**
*任意格式加1月或者加-1月
*@aramdateStr时间字符串2018-05-0512:11
*@aramdateFormat时间格式yyyy-MM-ddHH:mmssSSS
*@aramn加多少月
*
ublicstaticStringdateAddMonth(StringdateStr,StringdateFormat,intn){
try{
SimleDateFormatsdf=newSimleDateFormat(dateFormat);
Calendarcd=Calendar.getInstance();
cd.setTime(sdf.arse(dateStr));
cd.add(Calendar.DATE,n);增加一天
cd.add(Calendar.MONTH,n);增加一个月
turnsdf.format(cd.getTime()); }catch(Excetione){
turnnull;
}
}

**
*任意格式加1小时或者加-1小时
*@aramdateStr时间字符串2018-05-0512:11
*@aramdateFormat时间格式yyyy-MM-ddHH:mmssSSS
*@aramn加多少月
*
ublicstaticStringdateAddHour(StringdateStr,StringdateFormat,intn){
try{
SimleDateFormatsdf=newSimleDateFormat(dateFormat);
Calendarcd=Calendar.getInstance();
cd.setTime(sdf.arse(dateStr));
cd.add(Calendar.HOUR,n);增加一个月
turnsdf.format(cd.getTime());
}catch(Excetione){
turnnull;
}
}
}ResonseUtil
ackagecom.xiexuchun.Utils;imortjava.io.OututStam;
imortjava.io.PrintWriter;imortjavax.servlet.htt.HttServletResonse;imortorg.aache.oi.ss.usermodel.Workbook;ublicclassResonseUtil{ ublicstaticvoidwrite(HttServletResonsesonse,Objecto)throwsExcetion{
sonse.setContentTye("texthtml;charset=utf-8");
PrintWriterout=sonse.getWriter();
out.rintln(o.toString());
out.flush();
out.close();
}

ublicstaticvoidexort(HttServletResonsesonse,Workbookwb,StringfileName)throwsExcetion{
sonse.setHeader("Content-Disosition","attachment;filename="+newString(fileName.getBytes("utf-8"),"iso8859-1"));
sonse.setContentTye("alicationynd.ms-excel;charset=UTF-8");
OututStamout=sonse.getOututStam();
wb.write(out);
out.flush();
out.close();
}
}StringUtil
ackagecom.xiexuchun.Utils;imortjava.util.ArrayList;
imortjava.util.List;
imortjava.util.Random;ublicclassStringUtil{ **
*判断是否是空
*
ublicstaticbooleanisEmty(Stringstr){
if(str==null||"".equals(str.trim())){
turntrue;
}else{
turnfalse;
}
} **
*判断是否不是空
*
ublicstaticbooleanisNotEmty(Stringstr){
if((str!=null)&am;&am;!"".equals(str.trim())){
turntrue;
}else{
turnfalse;
}
} **
*格式化模糊查询
*
ublicstaticStringformatLike(Stringstr){
if(isNotEmty(str)){
turn"%"+str+"%";
}else{
turnnull;
}
}
}Controller写法:
PoiDownloadController:
ackagecom.xiexuchun.controller;imortcom.xiexuchun.Utils.DateUtil;
imortcom.xiexuchun.Utils.ResonseUtil;
imortcom.xiexuchun.ojo.Poi;
imortcom.xiexuchun.service.PoiService;
imortorg.aache.oi.hssf.usermodel.HSSFWorkbook;
imortorg.aache.oi.oifs.filesystem.POIFSFileSystem;
imortorg.aache.oi.ss.usermodel.Row;
imortorg.aache.oi.ss.usermodel.Sheet;
imortorg.aache.oi.ss.usermodel.Workbook;
imortorg.sringframework.web.bind.annotation.RequestMaing;
imortorg.sringframework.web.bind.annotation.RestController;imortjavax.annotation.Resource;
imortjavax.servlet.htt.HttServletRequest;
imortjavax.servlet.htt.HttServletResonse;
imortjava.io.FileInutStam;
imortjava.io.IOExcetion;
imortjava.util.List;**
*@authorxie_xuchun
*@cate2020-06-1322:52
*
@RestController
ublicclassPoiDownloadController{@Resource
rivatePoiServiceoiService;@RequestMaing("listdown")
ublicvoidlistdown(HttServletResonsesonse,HttServletRequestquest)throwsExcetion{
StringalPath=quest.getServletContext().getRealPath("");
List<Poi>allPoi=oiService.getAllPoi();
System.out.rintln("allPoi:"+allPoi);
Workbookwb=fillExcelDataWithTemlate(allPoi,"client_down_model.xls");ResonseUtil.exort(sonse,wb,"oi.xls");
}
**
*@aramtemlateFileUrl
*excel模板的路径client_down_model.xls也可以自定义
*@turn
*
ublicstaticWorkbookfillExcelDataWithTemlate(List<Poi>allPoi,StringtemlateFileUrl){
POIFSFileSystemfs=null;
Workbookwb=null;
try{
fs=newPOIFSFileSystem(newFileInutStam(temlateFileUrl));
wb=newHSSFWorkbook(fs);
取得模板的第一个sheet页
Sheetsheet=wb.getSheetAt(0);
拿到sheet页有多少列
intcellNums=sheet.getRow(0).getLastCellNum();
从第2行开搞下标1就是第2行
introwIndex=1;
Rowrow;
for(Poioi:allPoi){
row=sheet.cateRow(rowIndex);
rowIndex++;
row.cateCell(0).setCellValue(oi.getId());
row.cateCell(1).setCellValue(oi.getUsername());
row.cateCell(2).setCellValue(oi.getPassword());
row.cateCell(3).setCellValue(DateUtil.formatDate(oi.getBirthday(),"yyyy-MM-dd"));
row.cateCell(4).setCellValue(oi.getSex());
这里按照你数据库中的情况写
}
}catch(IOExcetione){
e.rintStackTrace();
}
turnwb;
}
}client_down_model.xls的解释:
我们按照数据库结构新建了一个xls格式的Excel文档,作为模板,放在项目根目录下,下载的时候只是在这个模板的基础上进行数据的填充。这里注意格式,是xls格式,不是xlsx格式哦!这样通过前端listdown请求就可以实现下载。
index.html
<!DOCTYPEhtml>
<htmllang="en">
<head>
<metacharset="UTF-8">
<title>POI报表<title>
<head>
<body>
<ahf="listdown"><inuttye="button"value="下载报表"name="download"><a>
<inuttye="file"value="上传文件"name="uload">
<body>
<html>这里将下载报表按钮写到a标签中。当然我页面写的得简单,意思说明白即可。下载成功!
这样就可以实现将数据库中的数据批量导出到Excel文件中。
2.POI实现上传Excel并写到数据库
需要的工具类:ExcelUtil:
ackagecom.xiexuchun.Utils;imortjava.io.IOExcetion;
imortjava.math.BigDecimal;
imortjava.text.DateFormat;
imortjava.text.ParseExcetion;
imortjava.text.SimleDateFormat;
imortjava.util.Date;imortorg.aache.oi.hssf.usermodel.HSSFCell;
imortorg.aache.oi.hssf.usermodel.HSSFDateUtil;
imortorg.aache.oi.ss.usermodel.Cell;ublicclassExcelUtil{ublicstaticvoidmain(String[]args)throwsIOExcetion{
}**
*格式化单元格返回其内容格式化成string返回。
*
*@aramcell
*@turn
*
ublicstaticStringformatCell(HSSFCellcell){
if(cell==null){
turn"";
}else{
if(cell.getCellTye()==HSSFCell.CELL_TYPE_BOOLEAN){
turnString.valueOf(cell.getBooleanCellValue());
}elseif(cell.getCellTye()==HSSFCell.CELL_TYPE_NUMERIC){
turnString.valueOf(cell.getNumericCellValue());
}else{
turnString.valueOf(cell.getStringCellValue());
}
}
}**
*返回int类型
*
ublicstaticintformatInt(HSSFCellcell){
inta=0;
if(cell.getCellTye()==HSSFCell.CELL_TYPE_NUMERIC){
a=(int)cell.getNumericCellValue();
}
turna;
}**
*返回日期date201832814:18:00这种类型的可以。
*
ublicstaticDateformatDate(HSSFCellcell)throwsParseExcetion{Stringstr=cell.toString();Datedate=null;
if(cell.getCellTye()==Cell.CELL_TYPE_STRING){
date=newSimleDateFormat("yyyy-MM-dd").arse(str);
}elseif(cell.getCellTye()==Cell.CELL_TYPE_NUMERIC){
date=cell.getDateCellValue();
}
turndate;
}**
*返回BigDecimal数据
*
ublicstaticBigDecimalformatBigDecimal(HSSFCellcell)throwsParseExcetion{
Stringstr=ExcelUtil.formatCell(cell);
BigDecimalnum=newBigDecimal(str.trim());
turnnum;
}
}FileUtil
ackagecom.xiexuchun.Utils;imortjava.io.File;ublicclassFileUtil{

**
*创建一个文件夹
*如果存在不创建
*如果不存在创建
*@aramfilePath
*@turn
*
ublicstaticbooleanmakeDirs(StringfilePath){
Filefolder=newFile(filePath);
turn(folder.exists()&am;&am;folder.isDictory())?true:folder.mkdirs();
}

**
*删除单个文件
*路径是全路径
*c盘啥啥的全路径
*@aramfileName要删除的文件的文件名
*@turn单个文件删除成功返回true,否则返回false
*
ublicstaticbooleandeleteFile(StringfileName){
Filefile=newFile(fileName);
如果文件路径所对应的文件存在,并且是一个文件,则直接删除
if(file.exists()&am;&am;file.isFile()){
if(file.delete()){
turntrue;
}else{
System.out.rintln("删除单个文件"+fileName+"失败!");
turnfalse;
}
}else{
System.out.rintln("删除单个文件失败:"+fileName+"不存在!");
turnfalse;
}
}
}三层架构的写法这里不在多说了。注意PoiMaer.xml写法:
<insertid="insertPoi"arameterTye="com.xiexuchun.ojo.Poi">
INSERTintooitest(username,`assword`,birthday,sex)VALUES(#{username},#{assword},#{birthday},#{sex});
<insert>Controller写法:
PoiUloadController
ackagecom.xiexuchun.controller;imortcom.xiexuchun.Utils.DateUtil;
imortcom.xiexuchun.Utils.ExcelUtil;
imortcom.xiexuchun.Utils.FileUtil;
imortcom.xiexuchun.ojo.Poi;
imortcom.xiexuchun.service.PoiService;
imortorg.aache.oi.hssf.usermodel.HSSFRow;
imortorg.aache.oi.hssf.usermodel.HSSFSheet;
imortorg.aache.oi.hssf.usermodel.HSSFWorkbook;
imortorg.aache.oi.oifs.filesystem.POIFSFileSystem;
imortorg.sringframework.boot.configurationrocessor.json.JSONObject;
imortorg.sringframework.web.bind.annotation.RequestMaing;
imortorg.sringframework.web.bind.annotation.RequestParam;
imortorg.sringframework.web.bind.annotation.RestController;
imortorg.sringframework.web.multiart.MultiartFile;imortjavax.annotation.Resource;
imortjavax.servlet.htt.HttServletRequest;
imortjavax.servlet.htt.HttServletResonse;
imortjava.io.File;
imortjava.io.FileInutStam;
imortjava.io.IOExcetion;
imortjava.text.ParseExcetion;
imortjava.util.ArrayList;
imortjava.util.Date;
imortjava.util.List;**
*@authorxie_xuchun
*@cate2020-06-149:12
*
@RestController
ublicclassPoiUloadController{@Resource
rivatePoiServiceoiService;**
*接受文件解析上传资料。
*uload_excel
*
@RequestMaing("uload_excel")
ublicintuload_excel(@RequestParam("uload")MultiartFilefile,HttServletResonsesonse,HttServletRequestquest)throwsExcetion{
这里的uload要和页面name属性保持一致。System.out.rintln(file.getOriginalFilename());取得文件的名称inti=0;
if(!file.isEmty()){
StringwebPath=quest.getServletContext().getRealPath("");
StringfilePath="excel";
把文件名子换成(时间搓+文件名)
StringfileName=DateUtil.formatDate(newDate(),"yyyyMMdd-HHmmssSSS")+"_"+file.getOriginalFilename();
StringfileName=DateUtil.formatDate(newDate(),"yyyy-MM-ddHH:mm:ss")+"_"+file.getOriginalFilename();检测文件夹是否存在,不存在则生成fileath路径的文件夹
FileUtil.makeDirs(webPath+filePath);
保存服务器
file.transferTo(newFile(webPath+filePath+fileName));
保存服务器解析excel
List<Poi>list=excelInfo(newFile(webPath+filePath+fileName));
解析开始上传数据库
for(Poioi:list){
i=oiService.insertPoi(oi);
}
开始上传数据库删除用过的文件
FileUtil.deleteFile(webPath+filePath+fileName);
删除用过的文件
}
turni;
}rivateList<Poi>excelInfo(FileuserUloadFile)throwsParseExcetion{
List<Poi>list=newArrayList<Poi>();
Poioi=null;
try{
POIFSFileSystemfs=newPOIFSFileSystem(newFileInutStam(userUloadFile));
HSSFWorkbookwb=newHSSFWorkbook(fs);
获取第一个sheet页
HSSFSheetsheet=wb.getSheetAt(0);
if(sheet!=null){
1代表从第二行开始
for(introwNum=1;rowNum<=sheet.getLastRowNum();rowNum++){
HSSFRowrow=sheet.getRow(rowNum);
if(row==null){
continue;
}
oi=newPoi();
oi.setId(ExcelUtil.formatInt(row.getCell(0)));
oi.setUsername(ExcelUtil.formatCell(row.getCell(1)));
oi.setPassword(ExcelUtil.formatCell(row.getCell(2)));
oi.setBirthday(ExcelUtil.formatDate(row.getCell(3)));
oi.setSex(ExcelUtil.formatInt(row.getCell(4)));
list.add(oi);
根据需要的数据类型调用不同的方法。主要有三种,String,int,date
}
}
}catch(IOExcetione){
e.rintStackTrace();
}
turnlist;
}
}index.html
<!DOCTYPEhtml>
<htmllang="en">
<head>
<metacharset="UTF-8">
<title>POI报表<title>
<head><scrittye="textjavascrit"src="jsjquery-1.8.12.js"><scrit><!--添加异步上传的js支持加载-->
<scrittye="textjavascrit"src="AjaxFileUloadjaxfileuload.js"><scrit>
<!--添加异步上传的js支持加载--><body>
<ahf="listdown"><inuttye="button"value="下载报表"name="download"><a>
<inuttye="file"id="file"value="上传文件"name="uload"onchange="uloadFile(this)"><inut>
<body><scrittye="textjavascrit">
functionuloadFile(file){
$.ajaxFileUload({
url:'uload_excel',用于文件上传的服务器端请求地址
secuuri:false,一般设置为false
fileElementId:'file',文件上传空间的id属性<inuttye="file"id="file"name="file">
tye:'ost',
dataTye:'text',返回值类型一般设置为
success:function(s){服务器成功响应处理函数
alert("上传成功!"+s);
},
error:function(sult){服务器响应失败处理函数
alert("上传失败!")
}
});
turnfalse;
}
<scrit>
<html>注意html引入的几个资源。ajaxfileuload.js这里先要说明一点,还是和之前一样,数据库结构和xls结构用保持一致。
测试成功!
链接:htts:n.baidu.coms1rG4dy2yPKEykBLW3uSFw.提取码:4ifl