Java导出多sheet的Excel表格
程序员文章站
2022-07-13 12:58:21
...
导出表格代码做备份
Poi导出到Excel表格
主要maven的jar包
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>2.5.6</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version> 3.10-FINAL</version>
</dependency>
主要代码
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
public class PoiExcelExport {
/**
* 每一个sheet能存放多少数据
*/
private final int MAX_ROW;
/**
* 存放文件的位置
*/
private final String TEMP_PATH;
/**
* 文件名称
*/
private final String FILE_NAME;
/**
* 文件名称
*/
private String sheetName;
/**
* 每次查询完数据库的list长度都是100,该变量统计每次list的size
*/
private int amout = 0;
/**
* sheet表头
*/
private Set<String> columnTitle;
/**
* 确保每个sheet名称都不一样
*/
private AtomicInteger count = new AtomicInteger();
public PoiExcelExport() {
this(6000, "D:/tmp/excel/", UUID.randomUUID().toString());
}
public PoiExcelExport(int max_row) {
this(max_row, "D:/tmp/excel/", UUID.randomUUID().toString(), "sheet");
}
public PoiExcelExport(int max_row, String temp_path, String file_name) {
this(max_row, temp_path, file_name, "sheet");
}
/**
* @param max_row 每一个sheet能存放多少数据
* @param temp_path 存放文件的位置
* @param file_name 文件名
*/
public PoiExcelExport(int max_row, String temp_path, String file_name, String sheetName) {
MAX_ROW = max_row;
TEMP_PATH = temp_path;
FILE_NAME = file_name;
this.sheetName = sheetName;
}
/**
* @param wb 新建SXSSFWorkbook导出对象
*/
public void createFile(SXSSFWorkbook wb) {
File excelFile = new File(TEMP_PATH);
if (!excelFile.exists()) {
excelFile.mkdirs();
}
String excelPath = TEMP_PATH + FILE_NAME;
excelPath = excelPath + ".xlsx";
excelFile = new File(excelPath);
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(excelFile);
wb.write(fileOutputStream);
fileOutputStream.flush();
fileOutputStream.close();
} catch (Exception e) {
throw new RuntimeException("生成excel文件时出现异常");
}
}
/**
* @param list 数据
* @param wb SXSSFWorkbook对象
* @param isNewSheet 是否是新的sheet,如果是就用新的sheet名
* @param row 从第几行开始写
* @throws IOException
*/
public void textExport(List<Map<String, Object>> list, SXSSFWorkbook wb,
boolean isNewSheet, int row) throws IOException {
// 设置sheet的表头
if (this.getColumnTitle() == null) {
this.setColumnTitle(list.get(0).keySet());
}
String sheetName = isNewSheet ? this.sheetName + count.incrementAndGet() : this.sheetName + count.get();
SXSSFSheet sheet;
if (isNewSheet) {
//根据sheetName,新建sheet页
sheet = (SXSSFSheet) wb.createSheet(sheetName);
//设置表头
Row headRow = sheet.createRow(0);
int i = 0;
for (String title : this.getColumnTitle()) {
// 写入标题
Cell cell = headRow.createCell(i++);
cell.setCellValue(title);
}
} else {
sheet = (SXSSFSheet) wb.getSheet(sheetName);
}
//设置默认宽度sheet.setDefaultColumnWidth(20);
//设置具体内容
for (Map<String, Object> dataMap : list) {
// 创建新行
SXSSFRow dataRow = (SXSSFRow) sheet.createRow(row++);
Set<String> keys = dataMap.keySet();
// 设置第 i 个列的数据
int i = 0;
for (String key : keys) {
// 创建列,创建完之后自增 1,下一次循环创建下一列
Cell cell1 = dataRow.createCell(i);
Object o = dataMap.get(key);
// 判读是否为空
if (StringUtils.isNotBlank(String.valueOf(o))) {
// 如果是日期就格式化输出
String data = o instanceof Date ? formatDate(o) : String.valueOf(o);
// 设置表格宽度 +2 是为了比字符串更长一点,空出一点
sheet.setColumnWidth(i, (data.length() + 2) * 256);
// 写到表格里
cell1.setCellValue(data);
} else {
cell1.setCellValue("");
}
i++;
}
// 将数据刷新到磁盘
if (this.getAmout() % 1000 == 0) {
sheet.flushRows();
}
}
// 设置到此刻位置一共有多少条数据
this.setAmout(this.getAmout() + list.size());
}
/**
* 格式化日期
*
* @param val
* @return
*/
private String formatDate(Object val) {
return new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format((Date) val);
}
public int getMAX_ROW() {
return MAX_ROW;
}
public String getTEMP_PATH() {
return TEMP_PATH;
}
public String getFILE_NAME() {
return FILE_NAME;
}
public String getSheetName() {
return sheetName;
}
public int getAmout() {
return amout;
}
public AtomicInteger getCount() {
return count;
}
public void setColumnTitle(Set<String> columnTitle) {
this.columnTitle = columnTitle;
}
public Set<String> getColumnTitle() {
return columnTitle;
}
public void setAmout(int amout) {
this.amout = amout;
}
}
Test类
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import java.io.IOException;
import java.util.*;
public class Test {
public static void main(String[] args) throws IOException {
// 模拟数据库查数据多少次。
int end = 1;
// 判断第二次写数据从多少行开始写
int startNum = 0;
// 存放数据的list
List<Map<String, Object>> list = new ArrayList();
//新建SXSSFWorkbook导出对象并设置每1000条刷新数据到硬盘,大数据导出时防止内存溢出
SXSSFWorkbook wb = new SXSSFWorkbook(1000);
// 新建导出对象,可以自定义名字和位置和sheet名字
PoiExcelExport export = new PoiExcelExport();
// PoiExcelExport export = new PoiExcelExport(6000,"D:/tmp/excel/","测试表格","sheet名字");
// sheet表头名字,可以自定义,可以用map的key。默认是map的key。
Set<String> strings = new HashSet<>();
strings.add("序号");
strings.add("日期");
strings.add("数字");
strings.add("数字1");
export.setColumnTitle(strings);
// 模拟循环查询数据库
while (true) {
// 设置数据
list.addAll(LIST_DATA);
// 当查询五次之后开始向文件里写
if (list.size() % 500 == 0) {
if (export.getAmout() % export.getMAX_ROW() == 0) {
export.textExport(list, wb, Boolean.TRUE, 1);
startNum = 0;
} else {
export.textExport(list, wb, Boolean.FALSE, list.size() * (++startNum) + 1);
}
list.clear();
}
// 模拟查询完数据库
if (end == 121) {
export.textExport(list, wb, Boolean.TRUE, 1);
list.clear();
break;
}
end++;
}
export.createFile(wb);
}
private static List<Map<String, Object>> LIST_DATA;
static {
LIST_DATA = new ArrayList<>();
for (int i = 0; i < 100; i++) {
Map<String, Object> map = new LinkedHashMap();
map.put("name", i);
map.put("date", new Date());
map.put("key", "2832734897238412131322131231");
map.put("key1", "2832734897238412131322131231");
LIST_DATA.add(map);
}
}
}