poi基本使用
HSSF — 提供读写Microsoft Excle格式档案的功能。 03版本(后缀为.xls)
XSSF — 提供读写Microsoft Excle OOXML格式档案的功能。 07版本(后缀为.xlsx)
HWPF — 提供读写Microsoft Word格式档案的功能。
HSLF — 提供读写Microsoft PowerPoint格式档案的功能。
HDGF — 提供读写Microsoft Visio格式档案的功能。
poi中文api文档:
Apache POI 动态导入方法
依赖
<!--xls(03版)-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.2</version>
</dependency>
<!--xlsx(07版)-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>
web传excel文件简单导入
public static Map<?,?> importExcelData(MultipartFile file) throws IOException {
InputStream inputStream = file.getInputStream();//得到文件的输入流
Map excelData=new HashMap();//存储读取到的数据
Map<Integer, String> titleMap = new HashMap<>();//存储表头信息
Map<Integer, Map> contentsMap = new HashMap<>();//存储表格内容
Map<String,Integer> oppTitleMap = new HashMap<>();
Map<String,Integer> tipsMap = new HashMap<>();
if(file.getOriginalFilename().endsWith(".xlsx")){//07版
XSSFWorkbook wb = new XSSFWorkbook(inputStream);//建一个工作薄
XSSFSheet sheet = wb.getSheetAt(0);//从文档中的第几张表开始,可写循环读取
for (int i = sheet.getFirstRowNum(), rowCount = 0; rowCount < sheet.getPhysicalNumberOfRows(); i++) {
XSSFRow row = sheet.getRow(i);//工作表的行数
if (row == null) {
continue;
}
for (int j = row.getFirstCellNum(); j <= row.getLastCellNum(); j++) {
XSSFCell cell = row.getCell(j);//得到单元格信息
if (cell == null) {
continue;
}
//日期格式判断
CellType cellType = cell.getCellType();
String value =null;//单元格中数据
if(cellType==CellType.NUMERIC){
if (DateUtil.isCellDateFormatted(cell)){
Date date = cell.getDateCellValue();
//格式转换
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
value = sdf.format(date);
}else {
cell.setCellType(CellType.STRING);//设置单元格数据格式
value = cell.getStringCellValue();
// value=String.valueOf(cell.getNumericCellValue());
}
}else{
cell.setCellType(CellType.STRING);
value = cell.getStringCellValue();
}
if (rowCount == 0) {//表头
titleMap.put(j, value);
if(oppTitleMap.get(value) != null){
tipsMap.put("出现重复标题:"+value,j);
continue;
}
oppTitleMap.put(value,j);
} else {//表内容
if (titleMap.size() == 0) {
return null;
}
Map contentMap = null;
if(contentsMap.get(rowCount)==null){
contentMap=new HashMap();
}else{
contentMap=contentsMap.get(rowCount);
if(contentMap.get(titleMap.get(j)) != null){
continue;
}
}
contentMap.put(titleMap.get(j), value);
contentsMap.put(rowCount,contentMap);
}
}
rowCount++;//下一行
}
}
if(file.getOriginalFilename().endsWith(".xls")){//03版
HSSFWorkbook wb = new HSSFWorkbook(file.getInputStream());//创建工作簿
HSSFSheet sheet = wb.getSheetAt(0);//得到表
for (int i = sheet.getFirstRowNum(), rowCount = 0; rowCount < sheet.getPhysicalNumberOfRows(); i++) {
HSSFRow row = sheet.getRow(i);//得到行
if (row == null) {
continue;
}
for (int j = row.getFirstCellNum(); j <= row.getLastCellNum(); j++) {
HSSFCell cell = row.getCell(j);//得到列
if (cell == null) {
continue;
}
//日期格式判断
CellType cellType = cell.getCellType();
String value =null;//单元格中数据
if(cellType==CellType.NUMERIC){
if (DateUtil.isCellDateFormatted(cell)){
Date date = cell.getDateCellValue();
//格式转换
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
value = sdf.format(date);
}else {
cell.setCellType(CellType.STRING);
value = cell.getStringCellValue();
}
}else{
cell.setCellType(CellType.STRING);
value = cell.getStringCellValue();
}
if (rowCount == 0) {//表头
titleMap.put(j, value);
if(oppTitleMap.get(value) != null){
tipsMap.put("出现重复标题:"+value,j);
continue;
}
oppTitleMap.put(value,j);
} else {//表内容
if (titleMap.size() == 0) {
return null;
}
Map contentMap = null;
if(contentsMap.get(rowCount)==null){
contentMap=new HashMap();
}else{
contentMap=contentsMap.get(rowCount);
if(contentMap.get(titleMap.get(j)) != null){
continue;
}
}
contentMap.put(titleMap.get(j), value);
contentsMap.put(rowCount,contentMap);
}
}
rowCount++;//下一行
}
}
inputStream.close();//关闭流
excelData.put("contents",contentsMap);//数据内容
excelData.put("title",titleMap);//表头
excelData.put("oppTitle",oppTitleMap);//表头索引
excelData.put("tips",tipsMap);//提示
return excelData;
}
说明:
1、获取表头:Map titleMap = (Map) excelData.get("title");
对应数据key从0开始,获得每个单元格的数据。
2、获取内容:Map contents = (Map) excelData.get("contents");
对应数据key从1开始,获得每一行与表头对应的数据map,key为表头内容,value为对应行单元格内容。
3、在文件传入时可以做一个校验,校验格式是否为.xls 或 .xlsx
4、日期格式不支持自定义,仅支持默认日期格式
其他poi
EasyPoi
基于entity变量上的注解,非常简单的一种方式,兼容性很好
<!--easypoi springboot-->
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-spring-boot-starter</artifactId>
<version>4.4.0</version>
</dependency>
阿里easyExcel
同样基于注解的形式,对动态表头导出支持性比较好。
<!--easyexcel-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.2.6</version>
</dependency>
java web项目前端ajax请求后端导出Excel
前端ajax请求
$.ajax({
type: "POST",
data:JSON.stringify({数据}),
contentType: 'application/json',
xhrFields: {responseType: "blob"},
url: exportUrl,
success: function (result) {
var link = document.createElement('a');
let blob = new Blob([result], {type: 'application/vnd.ms-excel'});
link.style.display = 'none';
link.href = URL.createObjectURL(blob);
link.setAttribute('download', "文档名称.xlsx");
document.body.appendChild(link);
link.click();
document.body.removeChild(link)
layer.msg("导出成功!");
},
error: function(){
layer.msg("导出失败!");
}
});
//使用layui的方法纯前端导出
// var fileName='文档名称.xlsx';
// var datas = [];
// var map ={};
// for(var i=3;i<colsArr.length-4;i++){
// if(colsArr[i].title=='负责部门' || colsArr[i].title=='负责人'){
// continue;
// }
// var dataName = "data_"+i;
// var hInfo=colsArr[i].title;
// map[dataName] = hInfo;
// }
// datas.push(map);
// layui.excel.exportExcel({
// sheet: datas
// }, fileName, 'xlsx');
后端Controller代码
/**
* Excel举措模板导出
* @return
*/
@PostMapping("/export")
@ApiOperation(value = "Excel举措模板导出", notes = "Excel举措模板导出")
public void export(@RequestBody 接收实体类,HttpServletResponse response) throws IOException {
XSSFWorkbook wb = new XSSFWorkbook();//创建工作簿
XSSFSheet sheet = wb.createSheet("表名");//创建表
XSSFRow headRow=sheet.createRow(0);//创建表头
//获取表头数据 headLis
for(int i = 0; i< headList.size();i++){
headItem =headList.get(i);
XSSFCell headRowCell=headRow.createCell(i);//创建表头单元格
headRowCell.setCellValue(headItem.getLmmiTitle());
//设置单元格中文字颜色为红色
if(true){
XSSFCellStyle cellStyle = wb.createCellStyle();
XSSFFont font = wb.createFont();
font.setColor(XSSFFont.COLOR_RED);
cellStyle.setFont(font);
headRowCell.setCellStyle(cellStyle);
}
//单选多选设置
if(StrUtil.equals("radio",headItem.getType()) || StrUtil.equals("checkbox",headItem.getType())){
DataValidationHelper helper = new XSSFDataValidationHelper(sheet);
// 给内容行设置下拉列表内容
CellRangeAddressList contentRowCellList = new CellRangeAddressList(1,1, i,i);// 数据有效性被设置对象
DataValidationConstraint dataValidationConstraint = helper.createExplicitListConstraint(headItem.getDataList().split("\n"));
DataValidation data_validation_list = helper.createValidation(dataValidationConstraint, contentRowCellList);
sheet.addValidationData(data_validation_list);
// 给表头创建一个提示,当包含数据验证的单元格收到焦点时,用户将看到该提示
DataValidation data_validation_view = helper.createValidation(dataValidationConstraint, new CellRangeAddressList(0,0, i,i));
if(StrUtil.equals("checkbox",headItem.getType())){
data_validation_view.createPromptBox("提示:", "多选列");
}else{
data_validation_view.createPromptBox("提示:", "单选列");
}
data_validation_view.setShowPromptBox(true);
sheet.addValidationData(data_validation_view);
//创建一个消息框,如果用户输入的值无效,将向用户显示该消息框。
dataValidation1.setErrorStyle(HSSFDataValidation.ErrorStyle.STOP);
dataValidation1.createErrorBox("提示", "不允许自己输入,请选择下拉框里的数据");
}
//日期行提示
if(StrUtil.equals("text-time",headItem.getType())){
DataValidationHelper helper = new XSSFDataValidationHelper(sheet);
// 创建一个提示,当包含数据验证的单元格收到焦点时,用户将看到该提示
DataValidationConstraint dataValidationConstraint = helper.createCustomConstraint(String.valueOf(DataValidationConstraint.ValidationType.DATE));
DataValidation data_validation_view = helper.createValidation(dataValidationConstraint, new CellRangeAddressList(0,0, i,i));
data_validation_view.createPromptBox("提示:", "不支持自定义日期格式");
data_validation_view.setShowPromptBox(true);
sheet.addValidationData(data_validation_view);
}
//首行数据列显示默认值
if(StrUtil.isNotEmpty(headItem.getDefaultValue())){
if(sheet.getRow(1)==null){
XSSFRow contentRow=sheet.createRow(1);//创建内容
XSSFCell contentRowCell=contentRow.getCell(i);
if(contentRowCell==null){
contentRowCell = contentRow.createCell(i);
}
contentRowCell.setCellValue(headItem.getDefaultValue());
}
}
}
//输出Excel文件
response.setContentType("application/vnd.ms-excel;charset=utf-8");
response.setHeader("Content-Disposition",
"attachment;filename=\"" + new String(("文档名称.xlsx").getBytes("gb2312"), "ISO8859-1"));
OutputStream output=response.getOutputStream();
wb.write(output);
output.close();
}