POI入门导出Excel及中文乱码问题
一.导入jar包
注意:
- poi-ooxml 和poi版本需要一致!
- 我这里使用的是3.7,之前用过4.1.1里面的一些方法会不同
<!--excel解析poi包 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.7</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.7</version>
</dependency>
二.编写Excel工具类
创建Excel流程:
- 需要新建一个Excel文件(HSSFWorkbook)
- 在Excel文件中创建一个工作表(HSSFSheet)
- 添加表头行并做简单的样式调整(HSSFRow.)
- 在表头行中添加对应的表列(HSSFCell)
- 添加表中的内容
public class ExcelUtil {
/**
*
* @param sheetName 工作表名
* @param title 表头
* @param values 表内容
* @param wb Excel表
* @return
*/
public static HSSFWorkbook getHSSFWorkbook(String sheetName, String[] title, String[][] values, HSSFWorkbook wb){
System.out.println(Arrays.toString(title));
//1.创建一个HSSFWorkbook,对应一个Excel文件
if (wb==null){
wb = new HSSFWorkbook();
}
//2.在wb中添加一个sheet
HSSFSheet sheet = wb.createSheet();
wb.setSheetName(0, sheetName);
//3.在sheet里面添加第0行
HSSFRow row = sheet.createRow(0);
//设置表头居中
HSSFCellStyle cellStyle = wb.createCellStyle();
cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
//4.声明列对象
HSSFCell cell = null;
//添加表头标题
for (int i = 0; i < title.length; i++) {
//第0行第i列
cell = row.createCell(i);
//列的样式
cell.setCellStyle(cellStyle);
//表中的编码
cell.setCellValue(HSSFCell.ENCODING_UTF_16);
//列中的数据
cell.setCellValue(title[i]);
}
//5.创建内容
for(int i=0;i<values.length;i++){
row = sheet.createRow(i + 1);
for(int j=0;j<values[i].length;j++){
//将内容按顺序赋给对应的列对象
row.createCell(j).setCellValue(values[i][j]);
}
}
return wb;
}
}
三.编写Controller层
@Controller
public class DownLoadController {
@Autowired
UserService userService;
@RequestMapping("/downLoad")
public String downLoad(HttpServletResponse response) throws Exception {
//获得数据
List<User> allUsers = userService.getAllUsers();
//excel 表头
String[] title = {"编号","姓名","密码","邮箱"};
//表名
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH.mm.ss");
String format = sdf.format(new Date());
String fileName = "用户信息表"+format+".xls";
//sheet名
String sheetName = "用户信息表";
//表内容
String[][] count = new String[allUsers.size()][title.length];
//循环得到表里面的内容
for (int i = 0; i < allUsers.size(); i++) {
count[i] = new String[title.length];
User user = allUsers.get(i);
count[i][0] = user.getId().toString();
count[i][1] = user.getName();
count[i][2] = user.getPassword();
count[i][3] = user.getEmail();
}
//创建HSSFWorkbook
HSSFWorkbook wb = ExcelUtil.getHSSFWorkbook(sheetName, title, count, null);
//获取输出流
OutputStream output = response.getOutputStream();
response.reset();
//设置分区中文名
//设置响应的编码
//下面三行是关键代码,处理乱码问题
response.setContentType("application/x-download");
response.setCharacterEncoding("utf-8");
//设置浏览器响应头对应的Content-disposition ,这样才会在浏览器中显示下载
//attachment :附件
response.setHeader("Content-disposition", "attachment;filename="+new String(fileName.getBytes("gbk"), "iso8859-1")+".xls");
//wb输出
wb.write(output);
output.close();
return "success";
}
}
四.结果
五.中文乱码问题
1.表头乱码问题:
在声明列对象时注明编码
注意:
要先声明编码,再设置列中的数据,不然表头会全部变成1。在Excel表中(short)1 就等于UTF-8
//4.声明列对象
HSSFCell cell = null;
//添加表头标题
for (int i = 0; i < title.length; i++) {
//第0行第i列
cell = row.createCell(i);
//设置列的样式
cell.setCellStyle(cellStyle);
//先设置表中的编码
cell.setCellValue(HSSFCell.ENCODING_UTF_16);
//再设置列中的数据
cell.setCellValue(title[i]);
}
2.工作表名乱码及内容乱码:
查看下Demo的编码是否是utf-8,我之前是GBK所以一直是乱码
3.下载的表名乱码:
在写入到硬盘中设置响应编码即可解决表名乱码问题
//设置响应的编码
//下面三行是关键代码,处理乱码问题
response.setContentType("application/x-download");
response.setCharacterEncoding("utf-8");
//设置浏览器响应头对应的Content-disposition ,这样才会在浏览器中显示下载
//attachment :附件
response.setHeader("Content-disposition", "attachment;filename="+new String(fileName.getBytes("gbk"), "iso8859-1")+".xls");
按照网上教程写的一个小Demo,有错误的地方欢迎指出!谢谢大家!