前言
之前给大家介绍了Excel在本地导入的基本操作(本期博客需要有前两期博客的基础才比较好理解,大家最好看一看哦),详情可见博客:
以及
但很多小伙伴,或者说看过我这篇博客:那些年Java走过的路 的小伙伴可能就会问了:Java大多是运用于B/S架构的项目,也就是浏览器/服务器模式的项目,所以我往往需要的是在浏览器端导出Excel,那么我到底该怎么写呢???
别担心,本期博客将解决这个问题!!!
编码开始
依赖
既然要在web端操作,肯定需要Web的依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
完整依赖如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- xls(03) -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.9</version>
</dependency>
<!-- xlsx(07) -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.9</version>
</dependency>
<!-- 日期格式化工具 -->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.10.1</version>
</dependency>
<!-- lombok的依赖,idea需按照lombok的插件-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>
实体类
再需要一个实体类来装数据:
package com.guqueyue.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
//lombok插件的注解
@Data // 若未使用lombok插件,请自行生成getter、setter以及toString方法
@AllArgsConstructor // 若未使用lombok插件,请自行生成有参构造方法
@NoArgsConstructor // 若未使用lombok插件,请自行生成无参构造方法
@Accessors(chain = true) // 开启链式编程
public class DemoData {
/**
* 书名
*/
private String bookName;
/**
* 作者
*/
private String author;
/**
* 时间
*/
private String dateTime;
}
控制层
接下来,我们在控制层编写代码就好了:
package com.guqueyue.controller;
import com.guqueyue.entity.DemoData;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.joda.time.DateTime;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import javax.swing.*;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* @ClassName ExportExcelController
* @Description excel导出相关的控制层
* @Author 古阙月
* @Date 2020/11/4 0:31
* @Version 1.0
**/
@RequestMapping("/exportExcel")
@RestController
public class ExportExcelController {
/**
* 列名数组
*/
static String[] rowNameArray = {"书名", "作者", "写作时间"};
/**
* 生成数据的方法
* @return
*/
private List<DemoData> getData() {
List<DemoData> dataList = new ArrayList<DemoData>();
for (int i = 0; i < 10; i++) {
DemoData data = new DemoData();
data.setBookName("平凡的世界" + i);
data.setDateTime(new DateTime().toString("yyyy-MM-dd HH:mm:ss"));
data.setAuthor("路遥" + i);
dataList.add(data);
}
return dataList;
}
/**
* 导出excel
* @param response
* @throws Exception
*/
@RequestMapping("/export")
public void testWrite03Web(HttpServletResponse response) throws Exception {
// 1.创建一个工作簿
Workbook workbook = new HSSFWorkbook();
// 2.创建一个工作表
Sheet sheet = workbook.createSheet("古阙月的书单");
// 3.创建第一行
Row row1 = sheet.createRow(0);
// 创建列名
for (int i = 0; i < rowNameArray.length; i++) {
Cell cell = row1.createCell(i);
cell.setCellValue(rowNameArray[i]);
}
// 遍历创建接下来的行
List<DemoData> dataList = getData();
for (int i = 0; i < dataList.size(); i++) {
Row row = sheet.createRow(i + 1);
int j = 0;
DemoData demoData = dataList.get(i);
// 获取反射对象
Class<?> clazz = demoData.getClass();
// 获取反射对象的所有属性,包括公有属性和私有属性
Field[] fields = clazz.getDeclaredFields();
// 遍历所有属性
for (Field field : fields) {
// 私有属性授权,方便访问
field.setAccessible(true);
// 赋值
String value = (String) field.get(demoData);
Cell cell = row.createCell(j);
cell.setCellValue(value);
j++;
}
}
/**
* 格式化当前日期,以便拼接文件名
*/
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
String date = sdf.format(new Date());
// 生成文件名
String fileName = "古阙月书籍表03" + date + ".xls";
/**
* 将生成的excel写入到浏览器端
*/
response.reset();
response.setContentType("application/ms-excel;charset=UTF-8");
try {
response.addHeader("Content-Disposition", "attachment;filename=\""
+ new String((fileName).getBytes("GBK"),
"ISO8859_1") + "\"");
OutputStream out = response.getOutputStream();
// 写入
workbook.write(out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
看见代码不要慌,其实跟上期博客相比,主要多了这么些代码而已:
/**
* 将生成的excel写入到浏览器端
*/
response.reset();
response.setContentType("application/ms-excel;charset=UTF-8");
try {
response.addHeader("Content-Disposition", "attachment;filename=\""
+ new String((fileName).getBytes("GBK"),
"ISO8859_1") + "\"");
OutputStream out = response.getOutputStream();
// 写入
workbook.write(out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
运行
运行SpringBoot程序,在浏览器端输入:http://localhost:8080/exportExcel/export (因为我这里没有配置端口,所以默认为8080
)
可以看到在浏览器下方成功导出了一个excel文件,点开一看:
完美!!!
小提醒
当然,我们在实际开发过程中是不可能让用户直接在浏览器端输入url来导出excel的,我们可能需要编写前端代码来发送请求。
切记,千万不要用ajax来发送请求,毕竟ajax发送请求都是由ajax引擎来发送和接收请求的,而不是浏览器!!!
本博主就因为这个发送的问题困扰了几个小时!用location.href
即可:
location.href = "url";
比如没有拦截器等配置的情况之下,本篇博客中的url就是:http://localhost:8080/exportExcel/export
好了,本期博客到此结束,敬请期待下期博客,我们不见不散