目录
示例一
- 依赖
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.5</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.2.3</version>
</dependency>
注意:放在resource目录下的xls与xlsx文件在编译打包时会被转码压缩,导致客户端在下载到资源后无法正常打卡,解决方法https://www.cnblogs.com/mr-yang-localhost/p/9702577.html
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.poi.excel.ExcelWriter;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
/**
* excel工具
*/
public class ExcelUtil extends cn.hutool.poi.excel.ExcelUtil {
private static final String XLS_SUFFIX = ".xls";
private static final String EXCEL_XLS_CONTENT_TYPE = "application/vnd.ms-excel;charset=utf-8";
private static final String XLSX_SUFFIX = ".xlsx";
private static final String EXCEL_XLSX_CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8";
/**
* 导出excel文件
*
* @param resp 响应对象
* @param data 文件数据
* @param isXlsxType excel类型
*/
public static void exportExcelFile(HttpServletResponse resp, ExcelData data, Boolean isXlsxType) throws IOException {
ExcelWriter writer;
StringBuilder fileName = new StringBuilder("attachment;filename=" + URLEncoder.encode(data.getFileName(), StandardCharsets.UTF_8));
if (isXlsxType) {
writer = getWriter(isXlsxType);
fileName = fileName.append(XLSX_SUFFIX);
resp.setContentType(EXCEL_XLSX_CONTENT_TYPE);
} else {
writer = getWriter();
fileName = fileName.append(XLS_SUFFIX);
resp.setContentType(EXCEL_XLS_CONTENT_TYPE);
}
resp.setHeader("Content-Disposition", fileName.toString());
writer.renameSheet(data.getSheetName());
if (ObjectUtil.isNotNull(data.getTitle())) {
writer.merge(data.getRows().get(0).size() - 1, data.getTitle());
}
writer.write(data.getRows(), true);
writer.flush(resp.getOutputStream());
writer.close();
}
}
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.List;
import java.util.Map;
/**
* excel 数据对象
*/
@Data
@Accessors(chain = true)
public class ExcelData {
private String fileName;
private String sheetName;
private String title;
private List<Map<String, ?>> rows;
}
示例二
注意:放在resource目录下的xls与xlsx文件在编译打包时会被转码压缩,导致客户端在下载到资源后无法正常打卡,解决方法https://www.cnblogs.com/mr-yang-localhost/p/9702577.html
pom依赖
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.9</version>
</dependency>
导出工具
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class ExportExcelTool {
/**
* 导出excel 包含多个sheet
*
* @param response 响应信息
* @param dataList 需导出的数据
* @param fileName 文件名称.xls
*/
public static void exportSheet(HttpServletResponse response, List<ExcelData> dataList, String fileName) {
try {
// 创建工作簿对象
HSSFWorkbook workbook = new HSSFWorkbook();
for (int k = 0; k < dataList.size(); k++) {
ExcelData data = dataList.get(k);
// 创建工作表
createSheet(workbook, data);
}
if (workbook != null) {
try {
response.setHeader("content-Type", "application/vnd.ms-excel");
// 下载文件的默认名称
response.setHeader("Content-Disposition", "attachment;filename="
+ URLEncoder.encode(fileName, "utf-8"));
OutputStream out = response.getOutputStream();
workbook.write(out);
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 创建表格sheet
*
* @param workbook 工作簿
* @param data sheet数据
* @return 封装完成后的sheet
*/
public static HSSFSheet createSheet(HSSFWorkbook workbook, ExcelData data) {
// 创建工作表
HSSFSheet sheet = workbook.createSheet(data.getName());
// 获取列头样式对象
HSSFCellStyle columnTopStyle = getColumnTopStyle(workbook);
// 单元格样式对象
HSSFCellStyle style = getStyle(workbook);
// 定义所需列数
int columnNum = data.getTitles().size();
// 在索引0的位置创建行(最顶端的行开始)
HSSFRow rowRowName = sheet.createRow(0);
// 将列头设置到sheet的单元格中
for (int n = 0; n < columnNum; n++) {
Map<String, String> titleMap = data.getTitles().get(n);
Iterator<Map.Entry<String, String>> iterator = titleMap.entrySet().iterator();
if (iterator.hasNext()) {
Map.Entry<String, String> entry = iterator.next();
// 创建列头对应个数的单元格
HSSFCell cellRowName = rowRowName.createCell(n);
// 设置列头单元格的数据类型
cellRowName.setCellType(HSSFCell.CELL_TYPE_STRING);
HSSFRichTextString text = new HSSFRichTextString(entry.getKey());
// 设置列头单元格的值
cellRowName.setCellValue(text);
// 设置列头单元格样式
cellRowName.setCellStyle(columnTopStyle);
if (StrUtil.isNotBlank(entry.getValue())) {
// 创建批注
HSSFPatriarch patr = sheet.createDrawingPatriarch();
// 创建批注位置
HSSFClientAnchor anchor = patr.createAnchor(0, 0, 0, 0, n,
1, n + 3, 3);
HSSFComment comment = patr.createCellComment(anchor);
// 设置批注内容
comment.setString(new HSSFRichTextString(entry.getValue()));
cellRowName.setCellComment(comment);
}
}
}
if (CollUtil.isNotEmpty(data.getRows())) {
// 将查询出的数据设置到sheet对应的单元格中
for (int i = 0; i < data.getRows().size(); i++) {
// 遍历每个对象
List<Object> objList = data.getRows().get(i);
if (CollUtil.isNotEmpty(objList)) {
// 创建所需的行数
HSSFRow row = sheet.createRow(i + 1);
for (int j = 0; j < objList.size(); j++) {
HSSFCell cell = row.createCell(j);
if (objList.get(j) != null && !"".equals(objList.get(j))) {
// 设置单元格的值
cell.setCellValue(objList.get(j).toString());
} else {
cell.setCellValue("");
}
// 设置单元格样式
cell.setCellStyle(style);
}
}
}
}
return sheet;
}
/**
* 导出Excel
*
* @param response 响应信息
* @param data 需导出的数据
* @throws Exception 异常
*/
public static void exportExcel(HttpServletResponse response, ExcelData data) {
try {
// 创建工作簿对象
HSSFWorkbook workbook = new HSSFWorkbook();
// 创建工作表
createSheet(workbook, data);
if (workbook != null) {
try {
String fileName = data.getName() + ".xls";
response.setHeader("content-Type", "application/vnd.ms-excel");
// 下载文件的默认名称
response.setHeader("Content-Disposition", "attachment;filename="
+ URLEncoder.encode(fileName, "utf-8"));
OutputStream out = response.getOutputStream();
workbook.write(out);
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 导出Excel
*
* @param data 需导出的数据
* @throws Exception 异常
*/
public static void exportExcel(OutputStream out, ExcelData data) {
try {
// 创建工作簿对象
HSSFWorkbook workbook = new HSSFWorkbook();
// 创建工作表
createSheet(workbook, data);
if (workbook != null) {
try {
workbook.write(out);
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 列头单元格样式
*
* @param workbook 工作簿
* @return 单元格样式
*/
public static HSSFCellStyle getColumnTopStyle(HSSFWorkbook workbook) {
// 设置字体
HSSFFont font = workbook.createFont();
// 设置字体大小
font.setFontHeightInPoints((short) 11);
// 字体加粗
font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
// 设置字体名字
font.setFontName("Courier New");
// 设置样式;
HSSFCellStyle style = workbook.createCellStyle();
// 设置底边框;
style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
// 设置底边框颜色;
style.setBottomBorderColor(HSSFColor.BLACK.index);
// 设置左边框;
style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
//设置左边框颜色;
style.setLeftBorderColor(HSSFColor.BLACK.index);
// 设置右边框;
style.setBorderRight(HSSFCellStyle.BORDER_THIN);
// 设置右边框颜色;
style.setRightBorderColor(HSSFColor.BLACK.index);
// 设置顶边框;
style.setBorderTop(HSSFCellStyle.BORDER_THIN);
// 设置顶边框颜色;
style.setTopBorderColor(HSSFColor.BLACK.index);
// 在样式用应用设置的字体;
style.setFont(font);
// 设置自动换行;
style.setWrapText(false);
// 设置水平对齐的样式为居中对齐;
style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
// 设置垂直对齐的样式为居中对齐;
style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
return style;
}
/**
* 列数据信息单元格样式
*
* @param workbook 工作簿
* @return 单元格样式
*/
public static HSSFCellStyle getStyle(HSSFWorkbook workbook) {
// 设置字体
HSSFFont font = workbook.createFont();
// 设置字体名字
font.setFontName("Courier New");
// 设置样式;
HSSFCellStyle style = workbook.createCellStyle();
// 设置底边框;
style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
// 设置底边框颜色;
style.setBottomBorderColor(HSSFColor.BLACK.index);
// 设置左边框;
style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
// 设置左边框颜色;
style.setLeftBorderColor(HSSFColor.BLACK.index);
// 设置右边框;
style.setBorderRight(HSSFCellStyle.BORDER_THIN);
// 设置右边框颜色;
style.setRightBorderColor(HSSFColor.BLACK.index);
// 设置顶边框;
style.setBorderTop(HSSFCellStyle.BORDER_THIN);
// 设置顶边框颜色;
style.setTopBorderColor(HSSFColor.BLACK.index);
// 在样式用应用设置的字体;
style.setFont(font);
// 设置自动换行;
style.setWrapText(false);
// 设置水平对齐的样式为居中对齐;
style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
// 设置垂直对齐的样式为居中对齐;
style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
return style;
}
}
导出数据实体
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class ExcelData {
/**
* 名称
*/
private String name;
/**
* 标题 key 标题 value:备注
*/
private List<Map<String, String>> titles;
/**
* 行数据
*/
private List<List<Object>> rows = new ArrayList<>();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Map<String, String>> getTitles() {
return titles;
}
public void setTitles(List<Map<String, String>> titles) {
this.titles = titles;
}
public List<List<Object>> getRows() {
return rows;
}
public void setRows(List<List<Object>> rows) {
this.rows = rows;
}
}
示例三
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.5</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.2.3</version>
</dependency>
public static void exportForCarRecord(HttpServletResponse response, String titleTxt, List<String> headers, String fileName, LinkedList<LinkedList<Object>> data) throws IOException {
BigExcelWriter bigWriter = ExcelUtil.getBigWriter();
// 设置自动换行
bigWriter.getStyleSet().getCellStyle().setWrapText(true);
// 垂直对齐
bigWriter.getStyleSet().getCellStyle().setVerticalAlignment(VerticalAlignment.CENTER);
// 水平对齐
bigWriter.getStyleSet().getCellStyle().setAlignment(HorizontalAlignment.LEFT);
// 设置字体
Font font = bigWriter.getWorkbook().createFont();
font.setFontName("Arial");
font.setFontHeightInPoints((short) 12);
bigWriter.getStyleSet().getCellStyle().setFont(font);
// 合并单元格,并往这个单元格写指定内容,不是用默认格式
bigWriter.merge(5, titleTxt, false);
// 设置第一行的行高
bigWriter.setRowHeight(0, 40);
// 默认行高
bigWriter.setDefaultRowHeight(20);
// 设置当前行号
bigWriter.setCurrentRow(1);
// 设置列宽
bigWriter.setColumnWidth(0, 30);
bigWriter.setColumnWidth(1, 30);
bigWriter.setColumnWidth(2, 30);
bigWriter.setColumnWidth(3, 30);
bigWriter.setColumnWidth(4, 30);
bigWriter.setColumnWidth(5, 30);
// 写表格的title的内容
bigWriter.writeHeadRow(headers);
// 写具体的数据体
bigWriter.write(data);
// 导出到输出流中
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
bigWriter.flush(outputStream, true);
bigWriter.close();
// 配置响应对象
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
response.getOutputStream().write(outputStream.toByteArray());
}
调用示例
@ApiOperation("查询车辆出入场记录")
@AnonymousGetMapping("download")
public void downList(CarRecordQueryCriteria criteria, Pageable pageable, HttpServletResponse response) throws IOException {
Dict result = carRecordService.queryAll(criteria, pageable, true);
Map<String, Object> upAreaInfo = areaService.queryAll().get(0);
LinkedList<CarRecord> type = null;
LinkedList<CarRecord> records = result.get("content", type);
LinkedList<LinkedList<Object>> data = new LinkedList<>();
for (CarRecord carRecord : records) {
LinkedList<Object> objects = new LinkedList<>();
objects.add(carRecord.getSn());
objects.add(carRecord.getInTime());
objects.add(carRecord.getOutTime());
objects.add(carRecord.getStayHour());
if (MapUtil.getStr(upAreaInfo, "location").equals(carRecord.getLocation())) {
objects.add(MapUtil.getStr(upAreaInfo, "start_point") + " 至 " + MapUtil.getStr(upAreaInfo, "end_point"));
} else {
objects.add(MapUtil.getStr(upAreaInfo, "end_point") + " 至 " + MapUtil.getStr(upAreaInfo, "start_point"));
}
if ("0".equals(carRecord.getTimeoutFlag())) {
objects.add("是");
} else {
objects.add("否");
}
data.add(objects);
}
String fileName = "过车记录" + DateUtil.date().toString().replaceAll("\\s|:|-", "_") + ".xlsx";
String name = MapUtil.getStr(upAreaInfo, "parent_name");
String begin = null;
if (!CollectionUtils.isEmpty(records)) {
CarRecord carRecord = records.get(0);
begin = DateUtil.date(carRecord.getCreateTime().getTime()).toString();
} else {
begin = DateUtil.now().toString();
}
String end = DateUtil.now().toString();
String titleTxt = StrUtil.format("{}{}至{}过车记录\r\n导出时间:{}", name, begin, end, end);
List<String> headers = new ArrayList<>();
headers.add("车牌号");
headers.add("入场时间");
headers.add("出场时间");
headers.add("停留时间");
headers.add("进入区域");
headers.add("是否停留超时");
ExcelUtils.exportForCarRecord(response, titleTxt, headers, fileName, data);
}
效果