1、什么是POI
【简介】: POI简介(Apache POI),Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能。
【官网】: Apacche POI 官网
【主要包含模块】:
- HSSF - 提供读写Microsoft Excel格式档案的功能。(.xls)
- XSSF - 提供读写Microsoft Excel OOXML格式档案的功能。(.xlsx)
- HWPF - 提供读写Microsoft Word格式档案的功能。
- HSLF - 提供读写Microsoft PowerPoint格式档案的功能。
- HDGF - 提供读写Microsoft Visio格式档案的功能。
2、POI的基本适用
1、创建Maven项目导入如下的依赖
<dependencies>
<!--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>
<!--日期格式化工具-->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.10.1</version>
</dependency>
<!--test-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
2、创建测试类对excel功能进行测试
1、测试Excel2003写入功能
@Test
public void testExcel2003Write() throws IOException {
// 1 、创建工作薄
Workbook workbook = new HSSFWorkbook();
// 2、在工作薄中创建sheet
Sheet sheet = workbook.createSheet("疫苗统计");
// 3、在sheet中创建行
Row row0 = sheet.createRow(0);
// 4、创建单元格并存入数据
row0.createCell(0).setCellValue("今日人数");
row0.createCell(1).setCellValue("666");
Row row1 = sheet.createRow(1);
row1.createCell(0).setCellValue("统计时间");
row1.createCell(1).setCellValue(new DateTime().toString("YYYY-MM-dd HH:mm:ss"));
// 获取一个输出流并创建文件
FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\17538\\Desktop\\新建文件夹\\test2003.xls");
// 将文件输出到指定文件
workbook.write(fileOutputStream);
// 关闭输出流
fileOutputStream.close();
// 关闭工作薄
workbook.close();
}
【测试结果】:
2、测试Excel2007写入功能
@Test
public void testExcel2007Write() throws IOException {
// 1 、创建工作薄
Workbook workbook = new XSSFWorkbook();
// 2、在工作薄中创建sheet
Sheet sheet = workbook.createSheet("疫苗统计");
// 3、在sheet中创建行
Row row0 = sheet.createRow(0);
// 4、创建单元格并存入数据
row0.createCell(0).setCellValue("今日人数");
row0.createCell(1).setCellValue("666");
Row row1 = sheet.createRow(1);
row1.createCell(0).setCellValue("统计时间");
row1.createCell(1).setCellValue(new DateTime().toString("YYYY-MM-dd HH:mm:ss"));
// 将文件输出到指定文件
FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\17538\\Desktop\\新建文件夹\\test2007.xlsx");
workbook.write(fileOutputStream);
fileOutputStream.close();
workbook.close();
}
【注意事项】:
- 在2007的测试类中我们需要new XSSFWorkbok实现类。
- 保存文件的后缀必须为.xlsx
【测试结果】:
3、测试Excel2003大文件写入
@Test
public void testExcel2003BigDataWrite() throws IOException {
// 1、创建工作薄
Workbook workbook = new HSSFWorkbook();
// 2、创建sheet页
Sheet sheet = workbook.createSheet();
// 3、创建行
for (int i = 0; i <= 65536; i++) {
// 创建65536行
Row row = sheet.createRow(i);
// 每一行的第一个单元格写666
row.createCell(0).setCellValue("666");
}
// 4、输出
FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\17538\\Desktop\\新建文件夹\\test2003BigData.xls");
workbook.write(fileOutputStream);
fileOutputStream.close();
workbook.close();
}
【测试结果】:
【注意事项】:
- HSSFWorkbook最多只能处理65536行数据,如果超出65536行会抛出异常。
- 但是在处理过程中都是写入到缓存,最后一次才写入磁盘中,速度快。
4、测试Excel2007大文件写入
@Test
public void testExcel2007BigDataWrite() throws IOException {
long start = System.currentTimeMillis();
// 1、创建工作表
Workbook workbook = new XSSFWorkbook();
// 2、创建sheet
Sheet sheet = workbook.createSheet();
// 3、创建行
for (int i = 0; i <= 65536; i++) {
Row row = sheet.createRow(i);
row.createCell(0).setCellValue("56555");
}
// 4、写出
FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\17538\\Desktop\\新建文件夹\\test2007BigData.xlsx");
workbook.write(fileOutputStream);
fileOutputStream.close();
workbook.close();
System.out.println("总计耗时" + (System.currentTimeMillis() - start));
}
【测试结果】:
【注意事项】:
- 缺点:写数据时速度非常慢,非常耗内存,也会发生内存溢出,如100万条
- 优点:可以写较大的数据量,如20万条
- 过程中会产生临时文件,需要清除临时文件。
- 默认由100条记录被保存在内存中,如果超过这数量,则最前面的数据被写入临时文件。
5、测试Excel2007大文件快速写入
@Test
public void testExcel2007FastWriteBigData() throws IOException {
long start = System.currentTimeMillis();
// 1、创建工作薄
SXSSFWorkbook workbook = new SXSSFWorkbook();
// 2、创建sheet
Sheet sheet = workbook.createSheet();
// 3、创建行
for (int i = 0; i <= 65536; i++) {
Row row = sheet.createRow(i);
row.createCell(0).setCellValue("56555");
}
FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\17538\\Desktop\\新建文件夹\\test2007FastBigData.xlsx");
workbook.write(fileOutputStream);
fileOutputStream.close();
workbook.dispose();
workbook.close();
System.out.println("总计耗时" + (System.currentTimeMillis() - start));
}
【测试结果】:
6、测试Excel2003文件读取
@Test
public void test2003Read() throws IOException {
// 1、需要将文件变为输入流
FileInputStream fileInputStream = new FileInputStream("C:\\Users\\17538\\Desktop\\新建文件夹\\test2003BigData.xls");
// 2、创建工作薄
Workbook workbook = new HSSFWorkbook(fileInputStream);
// 3、获取sheet
Sheet sheetAt = workbook.getSheetAt(0);
// 4、获取总行数
int lastRowNum = sheetAt.getLastRowNum();
for (int i = 0; i <= lastRowNum; i++) {
Row row = sheetAt.getRow(i);
// 获取每一行的总列数
short lastCellNum = row.getLastCellNum();
for (int j = 0; j < lastCellNum; j++) {
String stringCellValue = row.getCell(j).getStringCellValue();
System.out.println("第" + i + "行的第" + j + "个单元格数据为" + stringCellValue);
}
}
workbook.close();
fileInputStream.close();
}
【测试结果】:
7、测试Excel2007文件读取
@Test
public void test2007Read() throws IOException {
// 1、需要将文件变为输入流
FileInputStream fileInputStream = new FileInputStream("C:\\Users\\17538\\Desktop\\新建文件夹\\test2007BigData.xlsx");
// 2、创建工作薄
Workbook workbook = new XSSFWorkbook(fileInputStream);
// 3、获取sheet
Sheet sheetAt = workbook.getSheetAt(0);
// 4、获取总行数
int lastRowNum = sheetAt.getLastRowNum();
for (int i = 0; i <= lastRowNum; i++) {
Row row = sheetAt.getRow(i);
// 获取每一行的总列数
short lastCellNum = row.getLastCellNum();
for (int j = 0; j < lastCellNum; j++) {
String stringCellValue = row.getCell(j).getStringCellValue();
System.out.println("第" + i + "行的第" + j + "个单元格数据为" + stringCellValue);
}
}
workbook.close();
fileInputStream.close();
}
【测试结果】:
6、测试Exce文件读取不同类型的数据
@Test
public void testExcelDifferentValue() throws IOException {
// 1、获取输入流
FileInputStream fileInputStream = new FileInputStream("C:\\Users\\17538\\Desktop\\新建文件夹\\商品信息表.xlsx");
// 2、创建工作薄
Workbook workbook = new XSSFWorkbook(fileInputStream);
// 3、获取sheet
Sheet sheet = workbook.getSheetAt(0);
// 4、获取总行数
int lastRowNum = sheet.getLastRowNum();
for (int i = 0; i <= lastRowNum; i++) {
Row row = sheet.getRow(i);
short lastCellNum = row.getLastCellNum();
for (int j = 0; j < lastCellNum; j++) {
Cell cell = row.getCell(j);
// String类型
if (CellType.STRING.equals(cell.getCellType())) {
System.out.println("单元格内容是String类型:" + cell.getStringCellValue());
} else if (CellType.NUMERIC.equals(cell.getCellType())) {
// 是否日期类型
if (DateUtil.isCellDateFormatted(cell)) {
System.out.println("单元格内容是Date类型:" + cell.getDateCellValue());
} else {
System.out.println("单元格内容是数值类型:" + cell.getNumericCellValue());
}
} else if (CellType.BOOLEAN.equals(cell.getCellType())) {
System.out.println("单元格内容是布尔类型:" + cell.getBooleanCellValue());
} else if (CellType.BLANK.equals(cell.getCellType())) {
System.out.println("单元格内容是空字符串:");
} else {
System.out.println("其他情况!");
}
}
}
workbook.close();
fileInputStream.close();
}
【测试结果】:
文章来源:https://www.toymoban.com/news/detail-723618.html
3、WEB环境中使用POI
1、添加对应的依赖
<!--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>
2、页面中添加导入按钮和点击事件
- 导出按钮
<a href="#" onclick="exportOP()">
<span class="glyphicon glyphicon-save"></span> 导出
</a>
- 点击事件
function exportOP(){
// window.open()当发现是导出请求的时候,会自动关闭页面在页面内部下载
window.open("/permission/export")
}
- 导出分析及基本实现
【注意事项】: - 导出的时候必须设置头信息为
response.setHeader("Content-Disposition","attachment;filename=permissionData.xlsx");
3、导入的分析及实现
【实现过程分析】:
文章来源地址https://www.toymoban.com/news/detail-723618.html
1、添加导入按钮
<a href="#" onclick="importOP()">
<span class="glyphicon glyphicon-open"></span> 导入
</a>
2、添加导入的模态框
<#-- 模态框 -->
<div class="modal fade" id="importModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">导入</h4>
</div>
<form class="form-horizontal" enctype="multipart/form-data" method="post" id="importForm">
<div class="modal-body">
<div class="form-group" style="margin-top: 10px;">
<label for="name" class="col-sm-3 control-label"></label>
<div class="col-sm-6">
<!-- 文件上传框 -->
<input id="uploadFile" type="file" name="file"/>
</div>
</div>
<div class="form-group" style="margin-top: 10px;">
<div class="col-sm-3"></div>
<div class="col-sm-6">
<a href="#" onclick="downloadTemplateOP()" class="btn btn-success" >
<span class="glyphicon glyphicon-download"></span> 下载模板
</a>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
<button type="button" onclick="importSave()" class="btn btn-primary btn-submit">保存</button>
</div>
</form>
</div>
</div>
</div>
3、添加导入按钮和下载模板的点击事件
- 导入按钮
function importOP(){
// 显示模态框
$("#importModal").modal("show");
}
- 下载模板
function downloadTemplateOP(){
// 从服务器获取指定模板
window.open("/permission/downloadTemplate")
}
4、添加保存的点击事件
function importSave(){
var $file1 = $("#uploadFile").val();//用户文件内容(文件)
// 判断文件是否为空
if ($file1 == "") {
Swal.fire({
text: "请选择上传的目标文件! ",
icon: 'warning',
})
return false;
}
var formData = new FormData();//这里需要实例化一个FormData来进行文件上传
formData.append("file",$("#uploadFile")[0].files[0]);
$.ajax({
type : "post",
url : "/permission/importExcel",
data : formData,
processData : false,
contentType : false,
success : function(data){
if (data.success) {
Swal.fire({
text: data.msg,
icon: 'success',
})
$("#importModal").modal("hide");
$('#table').bootstrapTable('refresh');
}else{
Swal.fire({
text: "请选择上传的目标文件! ",
icon: 'warning',
})
}}
});
}
5、后台接收请求
@RequestMapping("/importExcel")
@ResponseBody
public JsonResult importExcel(MultipartFile file){
try{
int count = permissionService.importExcel(file);
return new JsonResult(true,"成功导入:"+count+"条记录");
}catch(Exception ex){
return new JsonResult(false,"导入数据失败");
}
}
6、业务层实现导入
@Override
public int importExcel(MultipartFile file) throws IOException {
// 1、创建工作簿读取文件输入流
Workbook workbook = new XSSFWorkbook(multipartFile.getInputStream());
// 2、获取sheet页
Sheet sheet = workbook.getSheetAt(0);
// 3、获取总行数
int lastRowNum = sheet.getLastRowNum();
// 4、计数器记录成功记录树
int successCount = 0;
// 5、获取现有的权限数据
List<Permission> permissionList = permissionMapper.selectAll();
// 6、从第一行开始读取数据
for (int i = 1; i <= lastRowNum; i++) {
Row row = sheet.getRow(i);
String name = row.getCell(0).getStringCellValue();
String expression = row.getCell(1).getStringCellValue();
// 封装对象
Permission permission = new Permission();
permission.setName(name);
permission.setExpression(expression);
// 判断是否存在该权限,如果没有插入到数据库
if (!permissionList.contains(permission)) {
permissionMapper.insert(permission);
}
}
return successCount;
}
到了这里,关于12、POI之数据导入导出的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!