在日常的开发中,对于在Java中使用POI进行导入导入导出可以说是必不可少。再次记录一下,方便下次快速查找使用 。希望可以帮到各位小伙伴。
第一部分:表的讲解
这一部分明白之后,对于下面的讲解可以更好的展开。
第二部分:模板下载
应用场景:我们需要把Excel表格中的数据按照统一的格式给存放到数据库中,因此需要一个模板也是必不可少的。
思路如下:
1.点击模板下载,前端发送一个请求,它是一个流信息。
2.后台接口拿到这个请求之后,接着去执行方法。找到项目中存放模板的路径。
3.拿到路径之后,我们就可以进行操作了。
具体实现如下:
@RequestMapping("/dowonload")
public void downLoad(HttpServletResponse response,HttpServletRequest request) throws Exception {
// 获取当年
int year = Calendar.getInstance().get(Calendar.YEAR);
String valueOf = String.valueOf(year);
// 1.先定义模板文件名
String fileName = "test.xlsx";
// 2.获取用水计划模板绝对路径
String excelFilePath = this.getClass().getClassLoader().getResource("excel/test.xlsx").getFile();
// 3.根据获得的路径,创建文件实例
File f = new File(excelFilePath);
// 4.文件输入流(知识点)
FileInputStream fileInputStream = new FileInputStream(f);
// 5.创建一个工作簿
HSSFWorkbook wb = new HSSFWorkbook(fileInputStream);
// 6.设置工作簿样式
HSSFCellStyle lockstyle = wb.createCellStyle();
HSSFCellStyle lockstyle1 = wb.createCellStyle();
// 7.读取excel中的表(是工作表)
Sheet sheet = wb.getSheetAt(0);
// 9.读取数据
Map<String, Object> resutlMap = new HashMap<>();
resutlMap.put("id", "");
// 我们需要给模板填充一些数据,下载之后包含一些基础数据
List<Map> list = secondUnitDao.selectUser(resutlMap);
// 10、cellNum为 单元格的下标;
// 11、rowNum 为 第几行;
int cellNum = 0;
int rowNum = 2;
// 对所查询的数据进行判断
if (Utils.isNotEmpty(list)) {
// 8.行数
for (int i = 0; i < list.size(); i++) {
// 从第几行开始创建
Row rowData = sheet.createRow(rowNum);
// 从下标0开始创建每行单元格
Cell createCell = rowData.createCell(cellNum);
//为第一行第一列单元格赋值
createCell.setCellValue(list.get(i).getId());
// 锁定单元格
createCell.setCellStyle(lockstyle);
Cell createCell2 = rowData.createCell(cellNum+1);
createCell2.setCellValue(list.get(i).getSecondUnitName());
// 锁定单元格
createCell2.setCellStyle(lockstyle);
Cell createCell4 = rowData.createCell(cellNum+2);
createCell4.setCellValue(valueOf);
// 锁定单元格
createCell4.setCellStyle(lockstyle);
// 接着创建一行中的其他单元格
for (int j = 3; j < 16; j++) {
Cell createCell3 = rowData.createCell(j);
createCell3.setCellStyle(lockstyle1);
}
rowNum++;
}
}
// 9.接着使用数组缓冲流输出,
exresult(fileName, request, response);
wb.write(response.getOutputStream());
wb.close();
}
//定义一个私有的方法
private void responseResult(String fileName,HttpServletRequest request,HttpServletResponse response) throws UnsupportedEncodingException {
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");
} else {
fileName = new String(fileName.getBytes(), "ISO8859-1");
}
response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
response.setContentType("application/vnd.ms-excel");
}
到这里,模板下载就完成了。
第三部分:数据导入
应用场景:把模板填充好的数据导入到数据库中
思路如下:
1.点击导入Excel按钮,
2.发送请求到后台接口方法,拿到导入的文件流。
3.拿到对应的文件流之后,接着创建工作簿、创建工作表。
4.接着我们创建一个Litst
@RequestMapping("/Export")
public Result modelExport(@RequestParam("file") MultipartFile file,@RequestParam Map<String, Object> params, HttpServletRequest request) throws IOException {
Result result = new Result();
String originalFilename = file.getOriginalFilename();
String[] split = originalFilename.split("\\.");
String suffixName = split[1];
if ("xlsx".equals(suffixName) || "xls".equals(suffixName)) {
// 1、获取传入的文件流
InputStream inputStream = file.getInputStream();
List<WaterIndConfPojo> importExcelResult = G4Utils.importExcel(inputStream);
Result updateByExcelResult = iWaterIndConfService.updateByExcelResult(importExcelResult);
return updateByExcelResult;
}else {
result.setCode(300);
result.setMsg("数据导入失败,请下载模板导入 !");
}
return result;
}
// 拿到输入文件的输入流,把流拿到这个下面的这个方法
public static List<Map> importExcel(InputStream inputStream) throws IOException {
// 获取当年
int year = Calendar.getInstance().get(Calendar.YEAR);
String valueOf = String.valueOf(year);
// 定义一个List,用来存放excel表中的值
List<Map> list2= new ArrayList<Map>();
// 1、传入获取的工作流, workbook,是一个工作簿,使用excel能操作的这边它都可以操作,这一个操作,相当于是把Excel放到Java中使用
//Workbook wb = new XSSFWorkbook(inputStream);
HSSFWorkbook wb = new HSSFWorkbook(inputStream);
// 2、获取工作簿中的表,对表中的设置,通过下标去拿第一张表
Sheet sheet = wb.getSheetAt(0);
// 3、获取表格总的行数
int rowNumber = sheet.getPhysicalNumberOfRows();
// 从第二行开始读取每一行数据,我们设置的模板表头是在第一、第二行,下标从0开始。
for (int rowNum = 2; rowNum < rowNumber; rowNum++) {
// 每读取一行,实例化一个对象
Map map1= new Map();
// 获取工作表中第二行的数据
Row rowData = sheet.getRow(rowNum);
// 这个地方,要注意,取到的值要进行判空处理,同时也要对值的类型进行转换
if (rowData != null) {
map1.setXXX(rowData.getCell(0));
....
list2.add(map1);
}
}
// 循环结束后,把从excel表读取的对象放到excelList中。
// 关闭流
inputStream.close();
// 返回list结果
return list
}
第四部分:数据导出
应用场景:我们需要把数据库的数据导出为Excel表格数据
思路如下:
1.点击 数据导出
2.后台接口拿到查询的参数,先去查询数据库,拿到对应的表格数据,
3.对数据进行处理,转成excel格式,输出就可以了。
具体实现如下:
@RequestMapping(value = "/exporToexcel",method = RequestMethod.POST)
public void exporToexcel(@RequestBody Map<String, Object> map,
HttpServletRequest request, HttpServletResponse response) {
// 1.取出map中的各个参数
// 2.查询数据库,拿到需要转换的表格数据。
// 3。获取文件名称
// 4.创建表格
HSSFWorkbook wb = new HSSFWorkbook();
//4.创建工作簿
HSSFSheet contWaterTable = wb.createSheet("测试表");
//5.添加默认列宽
contWaterTable.setDefaultColumnWidth(14);
//6.创建表头行
HSSFRow row = contWaterTable.createRow(0);
HSSFCell cell0 = row.createCell(0);
HSSFCell cell1 = row.createCell(1);
HSSFCell cell2 = row.createCell(2);
HSSFCell cell3 = row.createCell(3);
HSSFCell cell4 = row.createCell(4);
cell0.setCellValue("1");
cell1.setCellValue("1");
cell2.setCellValue("1");
cell3.setCellValue("1");
cell4.setCellValue("1");
//7.创建表头行
HSSFRow row1 = contWaterTable.createRow(1);
// 8.为第二行单元格设置值
HSSFCell srow1 = row1.createCell(0);
HSSFCell srow2 = row1.createCell(1);
HSSFCell srow3 = row1.createCell(2);
HSSFCell srow4 = row1.createCell(3);
HSSFCell srow5 = row1.createCell(4);
HSSFCell srow6 = row1.createCell(5);
HSSFCell srow7 = row1.createCell(6);
HSSFCell srow8 = row1.createCell(7);
HSSFCell srow9 = row1.createCell(8);
HSSFCell srow10 = row1.createCell(9);
HSSFCell srow11 = row1.createCell(10);
HSSFCell srow12 = row1.createCell(11);
HSSFCell srow13 = row1.createCell(12);
HSSFCell srow14 = row1.createCell(13);
HSSFCell srow15 = row1.createCell(14);
HSSFCell srow16 = row1.createCell(15);
HSSFCell srow17 = row1.createCell(16);
srow1.setCellValue("");
srow2.setCellValue("");
srow3.setCellValue("");
srow4.setCellValue("");
srow5.setCellValue("2");
srow6.setCellValue("3");
srow7.setCellValue("4");
srow8.setCellValue("5");
srow9.setCellValue("6");
srow10.setCellValue("7");
srow11.setCellValue("8");
srow12.setCellValue("9");
srow13.setCellValue("10");
srow14.setCellValue("11");
srow15.setCellValue("12");
srow16.setCellValue("13");
srow17.setCellValue("14");
//合并行、列
contWaterTable.addMergedRegion(new CellRangeAddress(0, 1, 0,0));
contWaterTable.addMergedRegion(new CellRangeAddress(0, 1, 1,1));
contWaterTable.addMergedRegion(new CellRangeAddress(0, 1, 2,2));
contWaterTable.addMergedRegion(new CellRangeAddress(0, 1, 3,3));
contWaterTable.addMergedRegion(new CellRangeAddress(0, 0, 4,16));
// 10.创建一个数组
String[] row_List = new String[17];
// 7.循环数据,把对应的数据存放到一个数组,逐个读取
int k =listResult.size() ;
int n = 0;
int s = 1;
// 获取行数
for (int j = 2; j <listResult.size()+2; j++) {
// 逐行读取表格数据
Map<String, Object> map2 = listResult.get(n);
n++;
//序号
String sn = String.valueOf(s++);
// 获取 map2中对应的数据
// 把所要填充的值放到数组中
row_List[0] = sn;
row_List[1] = "";
row_List[2] = "";
row_List[3] = "";
row_List[4] = "";
row_List[5] = "";
row_List[6] = "";
row_List[7] = "";
row_List[8] = "";
row_List[9] = "";
row_List[10] = "";
row_List[11] = "";
row_List[12] = "";
row_List[13] = "";
row_List[14] = "";
row_List[15] = "";
row_List[16] = "";
if (!(j == k+2)) {
// 从第二行开始创建表格
HSSFRow row2 = contWaterTable.createRow(j);
// 创建每一行的单元格数
for (int m = 0; m < row_List.length; m++) {
// 创建单元格
HSSFCell createCell = row2.createCell(m);
// 为每个单元格赋值
createCell.setCellValue(row_List[m]);
}
}
}
//8.生成文件名
OutputStream outputStream =null;
try {
// 文件名称
fileName = yr+"ceshi"+".xls";
String codedFileName = URLEncoder.encode(fileName,"UTF-8");
response.setContentType("application/x-msdownload");
response.setCharacterEncoding("utf-8");
response.setHeader("Content-Disposition", "attachment; filename=" +codedFileName);
//设置标头
outputStream = response.getOutputStream();
wb.write(outputStream);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
outputStream.flush();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
至此,有关Java中使用POI对表格数据导入、导出、以及下载,都已经讲解完了,明天会巩固一下流的知识,并记录整理下来。