前景:java中操作图形化API难免有些困难,这时就会有大神来封装这些API

目前热门:收费iText,免费apache-poi

使用办公文档的核心理想:把办公软件中的元素封装成java类,程序员只需要操作这些类就能够实现操作文档

pom依赖:

这里使用的是springboot进行整合

<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.1.2</version>
</dependency>

文档元素对应的java类

Excel                 java类

文件    ==》  HSSFWorkbook

页       ==》  HSSFSheet

列       ==》  HSSFRow

行       ==》  HSSFCell

样式   ==》  HSSFCellStyle

导出

测试

public static void main(String[] args) throws IOException {// 先获取到文件对象 HSSFWorkbookHSSFWorkbook workbook = new HSSFWorkbook();// 使用workbook创建页 HSSFSheetHSSFSheet sheet = workbook.createSheet("学生管理");// 当前页民称// 使用sheet创建行 HSSFRowHSSFRow row = sheet.createRow(0);// 第n行// 使用row创建HSSFCellHSSFCell cell = row.createCell(0); // 第n列// 在当前第0行第0列的表格中填写数据cell.setCellValue("姓名");// 在当前第0行第1列的表格中填写数据cell = row.createCell(1);cell.setCellValue("性别");// 创建输出流 文件夹必须存在 文件会自动创建       FileOutputStream os = new FileOutputStream("E:\\upload\\student.xls");workbook.write(os);// 关闭资源os.close();workbook.close();
}

模拟数据库导出 + 简化代码

public static void main(String[] args) throws IOException { // 准备一个数组存储元素String[] data = {"1","张三","男","16"};// 准备一个数组作为标题String[] title = {"id","姓名","性别","年龄"};// 先获取到文件对象 HSSFWorkbookHSSFWorkbook workbook = new HSSFWorkbook();// 使用workbook创建页 HSSFSheetHSSFSheet sheet = workbook.createSheet("学生管理");// 当前页民称// 使用sheet创建行 HSSFRowHSSFRow row = sheet.createRow(0);// 下标从0开始 代表第一行[第一行存放标题]for (int i = 0; i < title.length; i++) {// 循环一次就创建一列HSSFCell cell = row.createCell(i); // 使用下标作为当前列cell.setCellValue(title[i]); // 存放数组中的每条数据}// 创建5行数据for (int i = 1; i <= 5; i++) { // 第一行是标题 从第二行开始HSSFRow sheetRow = sheet.createRow(i); // 循环一次创建一行for (int j = 0; j < data.length; j++) {HSSFCell cell = sheetRow.createCell(j);cell.setCellValue(data[j]);}}// 创建输出流 文件夹必须存在 文件会自动创建FileOutputStream os = new FileOutputStream("E:\\upload\\student.xls");workbook.write(os);// 关闭资源os.close();workbook.close();
}

将文件下载到客户端

注意:使用同步请求

测试页面:

<script>function filedownload(){location.href='/fileDownLoadTest'}
</script>
<input type="button" value="下载" onclick="filedownload()">
@RequestMapping("/fileDownLoadTest")
public void fileDownLoadTest(HttpServletResponse response) throws IOException {// 设置响应格式response.setContentType("application/octet-stream;charset=UTF-8");response.addHeader("Content-Disposition","attachment;filename=student.xls");// 获取输入流ServletOutputStream out = response.getOutputStream();// 创建输入流进行读取FileInputStream fis = new FileInputStream("E:\\upload\\student.xls");byte[] bytes = new byte[1024];int i = 0;while ((i=fis.read(bytes))!=-1){ // 读out.write(bytes,0,i); // 写}// 关闭资源fis.close();out.flush();// Tomcat会自动关闭资源// out.close();
}

优化:

代码流程:

操作磁盘会影响效率,所以可以去操作内存,不去再写入磁盘

将数据写入Excel后,用创建好的HSSFWorkbook对象直接去写输出流对象

HSSFWorkbook wb = new HSSFWorkbook();
// ...... 此过程省略 包含【导出】【响应格式】
ServletOutputStream out = response.getOutputStream();
wb.write(out);
out.flush();
wb.close();

导入

首先对于文件的上传需要满足三个条件:

  1. 表单组件标签必须使用:<input type="file"/>
  2. 请求方式必须是POST:因为文件上传是以二级制的方式传递,只有POST请求可以解析二进制数据;而且使用POST请求,对于参数的长度是没有限制的。
  3. 表单的编码格式必须是multipart/form-data:根据HTTP协议规定,浏览器每次向服务器提交参数时,都会对参数进行统一编码,默认采用的编码格式为urlencoded,这种编码格式只支持文本数据。浏览器向服务端提交数据时,首先会把参数统一转换成字符串,然后在对这些数据进行统一urlencoded编码

测试文件上传

页面:

<form action="/fileUpload" method="post" enctype="multipart/form-data"><input type="file" name="myFile"><input type="submit" value="提交">
</form>

如果使用ajax发送请求:

const file = document.getElementById('activityFile')
// 获取到文件
const fileElement = file.files[0];
const formData = new FormData(); // 可以提交二级制数据
formData.append('activityFile',fileElement) // key要和后端形参一直
$.ajax({url : '/activity/saveActivityList',data : formData,dataType : 'json',processData : false, // 设置ajax提交参数之前 是否将参数统一转换成字符串 默认是truecontentType : false, // 设置ajax提交参数之前 是否将参数统一按urlencoded编码 默认是truetype : 'post',success(data){// 回调逻辑}
})

后端接收参数时,类型需要使用MultipartFile

注意:

如果项目使用的是SSM,需要在spring-mvc.xml文件中配置文件解析器

<!-- 配置上传文件工具 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><!-- 规范上传文件的信息(编码) --><property name="defaultEncoding" value="UTF-8"></property><!-- 限制上传文件的大小 b--><property name="maxUploadSize" value="10240000"></property>
</bean>

如果项目使用的springboot,不需要配置

后端:

@RequestMapping("/fileUpload")
@ResponseBody
public String fileUpload(MultipartFile myFile) throws IOException {// 获取源文件名String filename = myFile.getOriginalFilename();// 上传到那个路径File file = new File("E:\\upload\\"+filename);// 上传myFile.transferTo(file);return "ok";
}

测试文件导入:

注意:

  1. 在判断类型的时候,如果使用的是别的pom依赖,需要使用HSSFCell.xxx

  2. 如果使用的是博主的,使用CellType.xxx

public static void main(String[] args) throws IOException {// 指定导入的文件InputStream is = new FileInputStream("E:\\upload\\student.xls");// 创建HSSFWorkbookHSSFWorkbook wb = new HSSFWorkbook(is);// 通过wb对象获取HSSFSheetHSSFSheet sheet = wb.getSheetAt(0); // 通过下标获取,从0开始// 获取该页的最后一行下标,所以对于长度需要+1int lastRowNum = sheet.getLastRowNum();// 通过sheet对象获取HSSFRowfor (int i = 0; i < lastRowNum+1; i++) {HSSFRow row = sheet.getRow(i);// 获取该行最好一列【最后一列是下标+1 对于长度不需要+1】int lastCellNum = row.getLastCellNum();// 通过row对象获取HSSFCellfor (int j = 0; j < lastCellNum; j++) {HSSFCell cell = row.getCell(j);/*因为获取每一列数据时需要选择类型一个类型对应一个数字,数字不好记 但是常量好记HSSFCell封装了这些常量 这些常量对应着一些数字*/if (cell.getCellType() == CellType.NUMERIC){ // 数值System.out.print(cell.getNumericCellValue()+" ");}else if (cell.getCellType() == CellType.STRING){ // 字符串System.out.print(cell.getStringCellValue()+" ");}else if (cell.getCellType() == CellType.BOOLEAN){ // 布尔System.out.print(cell.getBooleanCellValue()+" ");}else if (cell.getCellType() == CellType.FORMULA){ // 空白System.out.print(cell.getCellFormula()+" ");}else{System.out.println(""+" ");}}// 换行System.out.println();}
}

效果:

添加到数据库

在Excel中,数值后面都会有"xxx.0" , 如果数据库字段类型是数值类型,需要将".0"截取掉,否则会出现类型转换异常

// 获取源文件名
String filename = activityFile.getOriginalFilename();
// 上传路径
File file = new File("E:\\upload\\"+filename);
// 上传
activityFile.transferTo(file);
// 读取
InputStream is = new FileInputStream(file);
// 创建HSSFWorkbook对象
HSSFWorkbook wb = new HSSFWorkbook(is);
HSSFSheet sheet = wb.getSheetAt(0);
int lastRowNum = sheet.getLastRowNum();
// 准备一个集合
List<TblActivity> list = new ArrayList<>();
for (int i = 1; i < lastRowNum+1; i++) {HSSFRow row = sheet.getRow(i);int lastCellNum = row.getLastCellNum();for (int j = 0; j < lastCellNum; j++) {HSSFCell cell = row.getCell(j);String str = "";if (cell.getCellType() == CellType.NUMERIC){ // 数值str = cell.getNumericCellValue()+"";}else if (cell.getCellType() == CellType.STRING){ // 字符串str = cell.getStringCellValue()+" ";}else if (cell.getCellType() == CellType.BOOLEAN){ // 布尔str = cell.getBooleanCellValue()+" ";}else if (cell.getCellType() == CellType.FORMULA){ // 空白str = cell.getCellFormula()+" ";}else{str = ""+" ";}// 根据业务自行添加if (j == 0){activity.setName(str);}else if (j == 1){activity.setStartDate(str);}else if (j == 2){activity.setEndDate(str);}else if (j == 3){activity.setCost(str);}else if (j == 4){activity.setDescription(str);}}// 遍历完一个对象就添加到集合中list.add(activity);
}
// 将集合传入mapper
int i = activityService.saveActivityByList(list);

mapper接口:

int insertActivityByList(List<实体类> list);

mapper xml:

<insert id="insertActivityByList" parameterType="实体类全路径">insert into tbl_activity(id, owner, name, start_date, end_date, cost, description, create_time, create_by)values<foreach collection="list" item="a" separator=",">(#{a.id},#{a.owner},#{a.name},#{a.startDate},#{a.endDate},#{a.cost},#{a.description},#{a.createTime},#{a.createBy})</foreach>
</insert>

优化:

/*String filename = activityFile.getOriginalFilename();
File file = new File("E:\\upload\\"+filename);
activityFile.transferTo(file);
InputStream is = new FileInputStream(file);
HSSFWorkbook wb = new HSSFWorkbook(is);*/
InputStream is = activityFile.getInputStream();
HSSFWorkbook wb = new HSSFWorkbook(is);

想轻松实现导出导入:

使用hutool工具类快速实现导出导入

使用POI实现Excel导出导入 详细解释相关推荐

  1. (B站云e办)SpringBoot开发项目实战记录(八)(Easy poi 完成excel导出导入)

    (B站云e办)SpringBoot开发项目实战记录(八) 一. pom依赖 二. 下载文件 2.1 jopo注释注解@Excel与@ExcelEntry 2.2 controller层 (完成exce ...

  2. 手摸手教学-利用原生POI对excel的导入导出以及阿里的easyexcel的基本操作

    文章目录 原生POI对excel的导入导出以及阿里的easyexcel的基本操作 首先是最原始的POI操作excel 其次是POI操作excel对数据库的导入导出 最后是阿里的easyexcel的简单 ...

  3. 蓄力-利用POI进行excel的导入导出(包含图片)

    这里写自定义目录标题 利用POI进行excel的导入导出 引入的jar包 excel导入 主方法: 将excel里面的图片转成数据 xls格式 xlsx格式 将图片数据转成字节流的方式传输到FTP服务 ...

  4. POI的Excel导出数据之后,单元格数据无法换行

    ** POI的Excel导出数据之后,单元格数据无法换行 问题描述: POI导出excel数据之后,代码中使用"\n"换行,导出数据之后数据并未换行,只有双击之后才展现换行效果,截 ...

  5. Apache POI操作Excel导出JAVABEAN对象方法

    2019独角兽企业重金招聘Python工程师标准>>> Apache POI操作Excel导出方法说明 Apache的POI组件是Java操作Microsoft Office办公套件 ...

  6. Poi实现Excel导出

    Poi实现Excel导出 Appache Poi提供了HSSFWorkbook操作2003版本的Excel文件, XSSFWorkbook操作2007版Excel文件. 简单的具体实现在网上有很多案例 ...

  7. SpringBoot+Vue+POI实现Excel的导入与导出

    文章目录 前言 POI中文操作API文档 导入Excel文件 导出Excel 总结 前言 继上一篇Excel的模板下载后,就此更新企业开发中常常需要使用到的Excel的导入与导出.Excel的解析需要 ...

  8. Poi实现Excel的导入

    前面写过一篇HSSF(实际上就是Poi)实现Excel导出的随笔,正好最近也有做导入的需求,那么就索性再写一篇Poi导入Excel的随笔吧. 其实,poi导入Excel和Poi导出Excel在实现步骤 ...

  9. java使用POI实现Excel批量导入数据。

    1.背景 项目中有使用easypoi,处理常规excel问题,但是现在有个需求,需要动态生成导出的报表字段.同时,根据导入的excel,增加数据信息.(有可能会出现,导入的报表是几天前下载的,不会最新 ...

最新文章

  1. 中点坐标公式 矩形_二次函数中矩形的存在性问题
  2. 详解spark任务提交至yarn的集群和客户端模式
  3. 一上来,就问原理,问上亿(MySQL)大表的索引优化,我的天...
  4. Flink kafka source sink 源码解析
  5. 前端测试框架Jest系列教程 -- Matchers(匹配器)
  6. 概率论实验 04 - | 基于Matlab的匹配滤波器
  7. CREO产品柔性建模 参数化 模具 TOP DOWN设计
  8. hprose php,hprose和swoole区别
  9. matlab数学实验报告面积,MATLAB插值实验报告数学实验
  10. 集成了谷歌翻译、百度翻译、有道翻译、和金山翻译的小助手软件
  11. erdas裁剪影像_ERDAS遥感图像的分幅裁剪
  12. C++ 命令行参数解析
  13. 《转》《七年之前与七年之后》
  14. 13.es slop参数实现近似匹配以及原理剖析和相关实验
  15. SQlserver基础学习
  16. 点线面的意义_对点线面的认知
  17. 作业——机器学习教你预测商品销售额
  18. 数据分析——mat文件
  19. 多校联考 CSP-J 2019 第三次模拟赛 题解
  20. 华为开发者联盟上架APP

热门文章

  1. 索尼开发新传感器为激光雷达提供助力,用于自动驾驶和其他应用
  2. 解决 NET::ERR_INCOMPLETE_CHUNKED_ENCODING 200 (OK)
  3. 家电企业如何利用APS生产排产应对市场变化调整生产?
  4. vue以post的方式发请求,传参在url中
  5. tzset函数与locatime时间函数的关系
  6. 求1-1/2+1/3-1/4+...+1/99-1/100
  7. spring自动填充
  8. html图片十字形,CSS3 十字架
  9. 头条案例登录注册功能
  10. Excel 删除数据temp 恢复