Java多sheet导出表格实现(通用)
程序员文章站
2024-03-20 21:27:46
...
使用场景
1、主从表数据同时导出,因为数据量较大,使用多sheet展示,可以增加数据可读性。
2、因为项目中多个地方有这个需求,所以花了一些时间编写了一个工具类,提高开发效率。
下面上干货:
实现思路
1、流开启后 ,创建一个Workbook 使用workbook创建多个sheet ,并设置不同的sheetName、表头 ,数据写入文本行后,关闭流。
2、通过反射、泛型 ,达到通用的目的
实现代码(包含单个sheet导出)
public class DataExportToExcelUtil {
private DataExportToExcelUtil() {
}
/**
* 工作薄
*/
private static HSSFWorkbook workbook;
//sheet
private static HSSFSheet sheet;
//标题行开始位置
private static final int TITLE_START_POSITION = 0;
//时间行开始位置
// private static final int DATEHEAD_START_POSITION = 1;
//表头行开始位置
private static final int HEAD_START_POSITION = 1;
//文本行开始位置
private static final int CONTENT_START_POSITION = 2;
/**
* 数据导出(多sheet)
*
* @param dataMap 对象集合 key为主表bean value为从表List集合
* @param titleMap 表头信息(对象属性名称--要显示的标题值)
* @param sheetName sheet名称和表头值(静态部分)
* @param sheetList sheet名称和表头值 (动态部分)(传入要获取的key对象的字段)
*/
public static void excelExportBacth(Map<?, ?> dataMap, Map<String, String> titleMap, List<String> sheetList, String sheetName,
String suffix, HttpServletResponse response, String fileName) {
try (OutputStream output = response.getOutputStream()) {
// 初始化workbook
initHSSFWorkbook(sheetName);
Set<?> dateSet = dataMap.keySet();
for (Object obj : dateSet
) {
//将sheetName赋给temp
String temp = sheetName;
//拼接sheetName
sheetName = getSheetName(obj, sheetList, sheetName);
//创建sheet;
sheet = workbook.createSheet(sheetName);
//标题行
createTitleRow(titleMap, sheetName);
//清空sheetName
sheetName = temp;
//时间行
// createDateHeadRow(titleMap);
//表头行
createHeadRow(titleMap);
// 文本行
createContentRow((List<?>) dataMap.get(obj), titleMap);
// 写入处理结果
}
response.reset();
response.setHeader("Content-disposition", "attachment; filename=" + URLEncoder.encode(fileName, "utf-8") + suffix);
response.setContentType("application/vnd.ms-excel;charset=utf-8");
response.setCharacterEncoding("utf-8");
workbook.write(output);
output.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* @param obj Map的key对象
* @param sheetList sheet名称和表头值 (动态部分)(传入要获取的key对象的字段)
* @param sheetName sheet名称和表头值(静态部分)
* @return String 拼接好的sheetName
*/
private static String getSheetName(Object obj, List<String> sheetList, String sheetName) {
try {
for (String str : sheetList) {
String method = "get" + str.substring(0, 1).toUpperCase() + str.substring(1);
Method m = obj.getClass().getMethod(method, null);
Object objectValue = m.invoke(obj, null);
if (objectValue != null) {
sheetName = objectValue.toString() + "--" + sheetName;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return sheetName;
}
/**
* 数据导出(单sheet)
*
* @param dataList 对象集合
* @param titleMap 表头信息(对象属性名称--要显示的标题值)
* @param sheetName sheet名称和表头值
*/
public static void excelExport(List<?> dataList, Map<String, String> titleMap, String sheetName,
String suffix, HttpServletResponse response, String fileName) {
// 初始化workbook
initHSSFWorkbook(sheetName);
sheet = workbook.createSheet();
//标题行
createTitleRow(titleMap, sheetName);
//时间行
// createDateHeadRow(titleMap);
//表头行
createHeadRow(titleMap);
// 文本行
createContentRow(dataList, titleMap);
// 写入处理结果
try (OutputStream output = response.getOutputStream()) {
response.reset();
response.setHeader("Content-disposition", "attachment; filename=" + URLEncoder.encode(fileName, "utf-8") + suffix);
response.setContentType("application/vnd.ms-excel;charset=utf-8");
response.setCharacterEncoding("utf-8");
workbook.write(output);
output.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 初始化
*
* @param sheetName
*/
private static void initHSSFWorkbook(String sheetName) {
workbook = new HSSFWorkbook();
}
/**
* 生成标题(第0行创建)
*
* @param titleMap 对象属性名称--表头显示名称
* @param sheetName sheet名称
*/
private static void createTitleRow(Map<String, String> titleMap, String sheetName) {
CellRangeAddress titleRange = new CellRangeAddress(0, 0, 0, titleMap.size() - 1);
sheet.addMergedRegion(titleRange);
HSSFRow titleRow = sheet.createRow(TITLE_START_POSITION);
HSSFCell titleCell = titleRow.createCell(0);
titleCell.setCellValue(sheetName);
//创建单元格,并设置值表头 设置表头居中
HSSFCellStyle styleTitle = titleCell.getCellStyle();
//水平居中
styleTitle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
//垂直居中
styleTitle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
}
/**
* 创建表头行(第二行创建)
*
* @param titleMap 对象属性名称--表头显示名称
*/
public static void createHeadRow(Map<String, String> titleMap) {
HSSFRow headRow = sheet.createRow(HEAD_START_POSITION);
int i = 0;
for (String entry : titleMap.keySet()) {
HSSFCell headCell = headRow.createCell(i);
headCell.setCellValue(titleMap.get(entry));
i++;
}
}
/**
* 创建文本行
*
* @param dataList 对象数据集合
* @param titleMap 对象属性名称--表头显示名称
*/
public static void createContentRow(List<?> dataList, Map<String, String> titleMap) {
try {
int i = 0;
for (Object obj : dataList) {
HSSFRow textRow = sheet.createRow(CONTENT_START_POSITION + i);
int j = 0;
int cellLength = 0;
Object objectValue;
for (String entry : titleMap.keySet()) {
if (obj instanceof Map) {
objectValue = ((Map) obj).get(entry);
} else {
String method = "get" + entry.substring(0, 1).toUpperCase() + entry.substring(1);
Method m = obj.getClass().getMethod(method, null);
objectValue = m.invoke(obj, null);
}
String value = "";
if (objectValue != null) {
value = objectValue.toString();
if (cellLength < value.getBytes().length) {
cellLength = value.getBytes().length;
}
}
HSSFCell textcell = textRow.createCell(j);
textcell.setCellValue(value);
j++;
}
if (cellLength != 0) {
sheet.setColumnWidth(i, cellLength * 2 * 256);
}
i++;
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
上一篇: 判断时间是否同一天
下一篇: 已知两个时间戳判断这两个时间是否在同一天