java中利用poi导入导出Excel表格
2020-07-24 本文已影响0人
小佳佳K3
java中利用poi导入导出Excel表格
最近多次用到,以此做记录。
需要用到的jar包
这里我贴出了pom,需要jar的朋友可以自行下载,或留言给我。
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.17</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.17</version>
</dependency>
编写工具类,导入导出Excel
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Excel导入导出工具类
*/
public class ExcelUtilss {
/**
* 构建一个Excel表格
*/
public static HSSFWorkbook createExcel(Map<String, List<String>> map, String[] str, String title) {
//创建一个HSSFWorkbook
//这个将构建一个新的Excel文件
HSSFWorkbook wb = new HSSFWorkbook();
//在HSSFWorkbook中添加有一个HSSFSheet
//构建一个新的工作簿
//并命名
HSSFSheet sheet = wb.createSheet("工作簿一");
/**
*构建一个标题行
*/
//创建单元格对象
HSSFCellStyle styleTitle = wb.createCellStyle();
//将单元格的格式设置为居中
styleTitle.setAlignment(HorizontalAlignment.CENTER);
//创建一个字体格式
HSSFFont font = wb.createFont();
//设置字体格式
font.setFontHeightInPoints((short) 20);
//将这个字体放入到单元格对象中
styleTitle.setFont(font);
//创建工作簿的标题行
//CellRangeAddress参数 1起始行号 2终止行号 3起始列号 4终止列号
sheet.addMergedRegion(new CellRangeAddress(0, 1, 0, 11));
//声明标题开始行
HSSFRow row = sheet.createRow(0);
//创建一个单元格
HSSFCell hssfCell = row.createCell(0);
//写入标题内容
hssfCell.setCellValue(title);
//将上面声明的标题单元格样式放入单元格
hssfCell.setCellStyle(styleTitle);
//创建正文单元格对象
//创建单元格对象
HSSFCellStyle style = wb.createCellStyle();
//设置单元格样式居中
style.setAlignment(HorizontalAlignment.CENTER);
//指定列宽
sheet.setDefaultColumnWidth(20);
//声明正文开始行,这里剔除了标题行
HSSFRow row1 = sheet.createRow(2);
//创建正文单元格
//这里写入单元格标题行
//读取传入的数组
HSSFCell cell = null;
for (int x = 0; x < str.length; x++) {
cell = row1.createCell((short) x);
cell.setCellValue(str[x]);
cell.setCellStyle(style);
}
//写入实体数据,map中list数据的顺序必须和数组str中的顺序一致
int i = 2;
HSSFCell cel = null;
//单元格样式对象
HSSFCellStyle sty = wb.createCellStyle();
//循环读取传入的集合对象
for (String st : map.keySet()) {
//设置行
row1 = sheet.createRow(i + 1);
//获取map中的list
List<String> list = map.get(st);
//创建单元格,并设置值
for (int j = 0; j < str.length; j++) {
//判断,根据自己的业务逻辑调整,进行日期转换
if (j == 0 || j == 13 || j == 14 || j == 15) {
cel = row.createCell((short) j);
cel.setCellType(CellType.NUMERIC);
cel.setCellValue(list.get(j));
//更改excel单元格自定义日期格式
HSSFDataFormat format = wb.createDataFormat();
sty.setDataFormat(format.getFormat("M月d日"));
cel.setCellStyle(sty);
} else {
//创建单元格
cel = row1.createCell((short) j);
//写入值
cel.setCellValue(list.get(j));
//写入样式
cel.setCellStyle(style);
}
}
//迭代行
i++;
}
return wb;
}
/**
* 读取excel文件
*
* @param file 读取的文件对象
* @return
* @throws Exception
*/
public static List<Map<String, String>> readExcel(File file) throws Exception {
//打开需要读取的文件
FileInputStream inputStream = new FileInputStream(file);
//读取工作簿
XSSFWorkbook wordBook = new XSSFWorkbook(inputStream);
//读取工作表,从0开始
XSSFSheet sheet = wordBook.getSheetAt(0);
//存储数据集合
List<Map<String, String>> mapList = new ArrayList<Map<String, String>>();
//存储单元格标题数据
Map<Integer, String> stringMap = new HashMap<Integer, String>();
//获取表格内容的最后一行的行数,获得循环次数
int lastRowNum = sheet.getLastRowNum();
//循环按行读取数据
for (int i = 0; i <= lastRowNum; i++) {
//存储单行数据集合
Map<String, String> map = new HashMap<String, String>();
//读取第i行
XSSFRow row = sheet.getRow(i);
//获取每一行的最后一列的列号,即总列数,循环次数
int columnNum = row.getLastCellNum();
//循环读取单行数据
for (int j = 0; j < columnNum; j++) {
//读取弟j个单元格对象
XSSFCell cell = row.getCell(j);
//设置单元格的数据类型数据类型
cell.setCellType(CellType.STRING);
//读取单元格的值
String value = cell.getStringCellValue();
//第一行是存储表头数据
if (i == 0) {
//单元格值
stringMap.put(j, value);
} else {
//否则存储表头对应单元格数据
map.put(stringMap.get(j), value);
}
}
if (i != 0) {
//将一行数据存入集合
mapList.add(map);
}
}
//关闭输入流
inputStream.close();
//关闭工作簿
wordBook.close();
return mapList;
}
}
工具类的使用
导出时:需要传入三个参数
Map<String, List<String>> map:是导出的数据
String[] str:单元格的标题数组
map集合中存储的String键值为标识当前数据处于哪一行,list数据则根据str数组的顺序存储对应的数据,一个list数据标识一行。
String title:工作簿的标题数据
导出文件后的下载输出
//通过工具类获取到了一个文件对象
HSSFWorkbook wb = ExcelUtilss.createExcel(map, str, title);
// 下载表格
OutputStream os = null;
try {
// 创建一个普通输出流
os = response.getOutputStream();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String fileName = formatter.format(new Date());
// 请求浏览器打开下载窗口
response.reset();
response.setCharacterEncoding("UTF-8");
// Content-disposition 告诉浏览器以下载的形式打开
String header = request.getHeader("User-Agent").toUpperCase();
if (header.contains("MSIE") || header.contains("TRIDENT") || header.contains("EDGE")) {
fileName = URLEncoder.encode(fileName, "utf-8");
fileName = fileName.replace("+", "%20"); // IE下载文件名空格变+号问题
} else {
fileName = new String(fileName.getBytes(), "ISO8859-1");
}
response.setHeader("Content-Disposition", "attachment; filename=" + fileName);// 要保存的文件名
response.setContentType("application/vnd.ms-excel");
response.setHeader("Access-Control-Allow-Origin", "*");
// 直接用数组缓冲输出流输出
wb.write(os);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
导入时将前端MultipartFile文件转换为File
File excelFile = MultipartFileToFile.multipartFileToFile(uploadImage);