官方poi地址:
Busy Developers' Guide to HSSF and XSSF Features
HSSFWorkbook、XSSFWorkbook、SXSSFWorkbook的区别:
◎HSSFWorkbook一般用于Excel2003版及更早版本(扩展名为.xls)的导出。
◎XSSFWorkbook一般用于Excel2007版(扩展名为.xlsx)的导出。
◎SXSSFWorkbook一般用于大数据量的导出。
/**
* 导出人事档案目录 组织数据
* @param list
* @param personnelIdToList
* @param qtyMap
*/
@Override
public void exportCatalogue(String year,
List list,
Map> personnelIdToList,
Map qtyMap) {
Map headMap = new LinkedHashMap();// 存放表头部信息
headMap.put("index", "序号");
headMap.put("name", "材料名称");
headMap.put("year", "年");
headMap.put("month", "月");
headMap.put("day", "日");
headMap.put("total", "页数");
headMap.put("remarks", "备注");
String zipBucketName = CommonConstants.BUCKET_NAME + year + "excel";
sysFileService.createBucket(zipBucketName);
String fileName = year + "excel/";
File f = new File(CommonConstants.BUCKET_PATH + zipBucketName + "/"+ fileName); //new的一个File对象
//先删除之前的文件夹
FileUtils.deleteQuietly(f);
sysFileService.craertTreeFile(zipBucketName, fileName);
for (TnPersonnel tnPersonnel : list) {
String serialNumber = tnPersonnel.getSerialNumber();
String name = tnPersonnel.getName();
String id = tnPersonnel.getId();
String title = serialNumber + name + ".xlsx";
String path = CommonConstants.BUCKET_PATH + zipBucketName + "/"+ fileName + title;
try {
JSONObject personnelJo = new JSONObject();
JSONArray catalogueJa = new JSONArray();
List trPersonnelCatalogues = personnelIdToList.get(id);
//添加大分类-
List newCata = this.creatTitle(trPersonnelCatalogues);
for (int i = 0; i < newCata.size(); i++) {
JSONObject jo = new JSONObject();
TrPersonnelCatalogue personnelCatalogue = newCata.get(i);
String catalogueId = personnelCatalogue.getId();
String cataDate = personnelCatalogue.getCataDate();
String createYear = "";
String month = "";
String day = "";
if(StringUtils.isNotBlank(cataDate)){
Date date = DateUtils.parseDate(cataDate, "yyyy-MM-dd");
createYear = DateUtils.formatDate(date, "yyyy");
month = DateUtils.formatDate(date, "MM");
day = DateUtils.formatDate(date, "dd");
}
String dateType = personnelCatalogue.getDateType();
String no = personnelCatalogue.getNo();
jo.put("index", no);
jo.put("name", personnelCatalogue.getName());
jo.put("year", createYear);
if("0".equals(dateType) || "2".equals(dateType) ||StringUtils.isBlank(dateType)){
jo.put("month", month);
}
if("2".equals(dateType) || StringUtils.isBlank(dateType)){
jo.put("day", day);
}
jo.put("total", qtyMap.get(catalogueId));
jo.put("remarks", "");
catalogueJa.add(jo);
}
personnelJo.put("name", name);
personnelJo.put("catalogueJa", catalogueJa);
// 生成文件临时存放目录
File destination = new File(path);
File dir = destination.getParentFile();
if (!dir.exists()) {
dir.mkdirs();
}
if (!destination.exists()) {
destination.createNewFile();
}
OutputStream outXlsx = new FileOutputStream(destination);
ExcleUtils.exportCatalogue(headMap, personnelJo, "yyyy-MM-dd", 6, outXlsx);
outXlsx.close();
} catch (Exception e) {
System.out.println("导出异常");
e.printStackTrace();
}
}
}
/**
* 导出人事档案目录 构建表头和页尾
*
* @param headMap 表头Map
* @param personnelJo 表格内容
* @param datePattern 日期格式
* @param colWidth 列宽
* @param out
*/
public static void exportCatalogue(Map headMap, JSONObject personnelJo,
String datePattern, int colWidth, OutputStream out) {
if (datePattern == null) datePattern = DEFAULT_DATE_PATTERN;
// 声明一个工作薄
SXSSFWorkbook workbook = new SXSSFWorkbook(1000);//缓存
workbook.setCompressTempFiles(true);
//加外框样式
CellStyle borderstyle = workbook.createCellStyle();
borderstyle.setBorderBottom(BorderStyle.THIN); //下边框
borderstyle.setBorderLeft(BorderStyle.THIN);//左边框
borderstyle.setBorderTop(BorderStyle.THIN);//上边框
borderstyle.setBorderRight(BorderStyle.THIN);//右边框
borderstyle.setAlignment(HorizontalAlignment.CENTER);//文字居中
borderstyle.setWrapText(true);
//居中样式
CellStyle centerCellStyle = workbook.createCellStyle();
centerCellStyle.setAlignment(HorizontalAlignment.CENTER);
//设置列宽
int minBytes = colWidth < DEFAULT_COLOUMN_WIDTH ? DEFAULT_COLOUMN_WIDTH : colWidth;//至少字节数
int[] arrColWidth = new int[headMap.size()];
// 产生表格标题行,以及设置列宽
String[] properties = new String[headMap.size()];
String[] headers = new String[headMap.size()];
int ii = 0;
// 生成一个表格
SXSSFSheet sheet = workbook.createSheet();
//默认列宽
sheet.setDefaultColumnWidth(5000);
for (Iterator iter = headMap.keySet().iterator(); iter
.hasNext(); ) {
String fieldName = iter.next();
properties[ii] = fieldName;
headers[ii] = headMap.get(fieldName);
ii++;
}
sheet.setColumnWidth(1, 8000);
// 页边距(左)
sheet.setMargin(SXSSFSheet.LeftMargin,( double ) 1 );
//设置打印页面为水平居中
sheet.setHorizontallyCenter(true);
//TODO 在POI的api中没有找到打印页面的得到方式
// Footer footer = sheet.getFooter();
// footer.setCenter( "第" + HeaderFooter.page() + "页,共 " + HeaderFooter.numPages()+"页" );
// footer.setCenter(sheet.);
//循环人员
Object name = personnelJo.get("name");
JSONArray catalogueJa = (JSONArray) JSONObject.toJSON(personnelJo.get("catalogueJa"));
//第一行,表名
SXSSFRow oneRow = sheet.createRow(0); //列头 rowIndex =1
SXSSFCell cell = oneRow.createCell(0);
cell.setCellValue("人事档案目录");
CellStyle cellStyle = workbook.createCellStyle();
Font font = workbook.createFont();
font.setFontHeightInPoints((short) 15);
font.setBold(true);
cellStyle.setFont(font);
cellStyle.setAlignment(HorizontalAlignment.CENTER);
cell.setCellStyle(cellStyle);
//合并单元格
sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, headers.length - 1));
//第二行,姓名
SXSSFRow nameRow = sheet.createRow(1); //列头 rowIndex =1
SXSSFCell nameCell = nameRow.createCell(0);
nameCell.setCellValue("姓名:" + name);
//合并单元格
sheet.addMergedRegion(new CellRangeAddress(1, 1, 0, headers.length - 1));
//第三行,表头
SXSSFRow headerOne = sheet.createRow(2); //列头 rowIndex =1
SXSSFRow headerTwo = sheet.createRow(3); //列头 rowIndex =1
for (int i = 0; i < headers.length; i++) {
SXSSFCell cell1 = headerOne.createCell(i);
cell1.setCellValue(headers[i]);
SXSSFCell cell2 = headerTwo.createCell(i);
cell2.setCellValue(headers[i]);
cell1.setCellStyle(borderstyle);
cell2.setCellStyle(borderstyle);
}
SXSSFCell dateCell = headerOne.createCell(2);
dateCell.setCellValue("材料形成日期");
dateCell.setCellStyle(borderstyle);
sheet.addMergedRegion(new CellRangeAddress(2, 3, 0, 0));
sheet.addMergedRegion(new CellRangeAddress(2, 3, 1, 1));
sheet.addMergedRegion(new CellRangeAddress(2, 2, 2, 4));
sheet.addMergedRegion(new CellRangeAddress(2, 3, 5, 5));
sheet.addMergedRegion(new CellRangeAddress(2, 3, 6, 6));
//生成表格内容
updateCell(catalogueJa, sheet, properties,
datePattern, borderstyle, headers, workbook, name, centerCellStyle);
try {
workbook.write(out);
workbook.close();
// boolean flag = workbook.dispose();//释放磁盘空间。处理在磁盘上支持这个工作簿的临时文件。调用该方法将使工作簿不可用。
// System.out.println(flag);//如果所有临时文件都被成功删除,则为真。
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* @param catalogueJa, sheet, properties, datePattern, borderstyle
* @return void
* @Description :导出人事档案目录-生成表格内容
* @author caohong
* @date 2021/11/3
*/
private static void updateCell(JSONArray catalogueJa,
SXSSFSheet sheet, String[] properties,
String datePattern, CellStyle borderstyle,
String[] headers, SXSSFWorkbook workbook,
Object name,CellStyle centerCellStyle) {
// 遍历集合数据,产生数据行
int rowIndex = 4;
//记录打印时每页行数
int printRow = 0;
//记录打印时每页总行数
int totalRow = 40;
//页码
int page = 1;
ArrayList noArr = creatTitle();
for (Object object : catalogueJa) {
JSONObject catalogueJo = (JSONObject) JSONObject.toJSON(object);
SXSSFRow dataRow = sheet.createRow(rowIndex);
for (int i = 0; i < properties.length; i++) {
Object o = catalogueJo.get(properties[i]);
String cellValue = "";
if (o == null) cellValue = "";
else if (o instanceof Date) cellValue = new SimpleDateFormat(datePattern).format(o);
else if (o instanceof Float || o instanceof Double)
cellValue = new BigDecimal(o.toString()).setScale(2, BigDecimal.ROUND_HALF_UP).toString();
else cellValue = o.toString();
if (i == 0 && noArr.indexOf(cellValue) > -1) {
if (printRow < totalRow) {
int j = totalRow - printRow;
//处理空行
for (int k = 1; k < j; k++) {
SXSSFRow dataRowBlank = sheet.createRow(rowIndex++);
for (int a = 0; a < properties.length; a++) {
if (k == 1) {
SXSSFCell newCell = dataRow.createCell(a);
//设置边框
newCell.setCellStyle(borderstyle);
}
SXSSFCell newCell = dataRowBlank.createCell(a);
//设置边框
newCell.setCellStyle(borderstyle);
}
}
}
//页尾
SXSSFRow endRow = sheet.createRow(rowIndex);
SXSSFCell pgaeCell = endRow.createCell(0);
pgaeCell.setCellValue("第" + page + "页");
pgaeCell.setCellStyle(centerCellStyle);
//合并单元格
sheet.addMergedRegion(new CellRangeAddress(rowIndex, rowIndex, 0, headers.length - 1));
rowIndex = rowIndex + 1;
//设置在特定行的添加分页符
sheet.setRowBreak(rowIndex - 1);
//添加分页符之后,重置打印行数
printRow = 0;
//第一行,表名
SXSSFRow oneRow = sheet.createRow(rowIndex); //列头 rowIndex =1
SXSSFCell cell = oneRow.createCell(0);
cell.setCellValue("人事档案目录");
CellStyle cellStyle = workbook.createCellStyle();
Font font = workbook.createFont();
font.setFontHeightInPoints((short) 15);
font.setBold(true);
cellStyle.setFont(font);
cellStyle.setAlignment(HorizontalAlignment.CENTER);
cell.setCellStyle(cellStyle);
//合并单元格
sheet.addMergedRegion(new CellRangeAddress(rowIndex, rowIndex, 0, headers.length - 1));
//第二行,姓名
SXSSFRow nameRow = sheet.createRow(rowIndex + 1); //列头 rowIndex =1
SXSSFCell nameCell = nameRow.createCell(0);
nameCell.setCellValue("姓名:" + name);
//合并单元格
sheet.addMergedRegion(new CellRangeAddress(rowIndex + 1, rowIndex + 1, 0, headers.length - 1));
//第三行,表头
SXSSFRow headerOne = sheet.createRow(rowIndex + 2); //列头
SXSSFRow headerTwo = sheet.createRow(rowIndex + 3); //列头
for (int b = 0; b < headers.length; b++) {
SXSSFCell cell1 = headerOne.createCell(b);
cell1.setCellValue(headers[b]);
SXSSFCell cell2 = headerTwo.createCell(b);
cell2.setCellValue(headers[b]);
cell1.setCellStyle(borderstyle);
cell2.setCellStyle(borderstyle);
}
SXSSFCell dateCell = headerOne.createCell(2);
dateCell.setCellValue("材料形成日期");
dateCell.setCellStyle(borderstyle);
sheet.addMergedRegion(new CellRangeAddress(rowIndex + 2, rowIndex + 3, 0, 0));
sheet.addMergedRegion(new CellRangeAddress(rowIndex + 2, rowIndex + 3, 1, 1));
sheet.addMergedRegion(new CellRangeAddress(rowIndex + 2, rowIndex + 2, 2, 4));
sheet.addMergedRegion(new CellRangeAddress(rowIndex + 2, rowIndex + 3, 5, 5));
sheet.addMergedRegion(new CellRangeAddress(rowIndex + 2, rowIndex + 3, 6, 6));
//加表头行数
rowIndex = rowIndex + 4;
//生成
dataRow = sheet.createRow(rowIndex);
page++;
}
SXSSFCell newCell = dataRow.createCell(i);
//填充内容
newCell.setCellValue(cellValue);
//设置边框
newCell.setCellStyle(borderstyle);
}
rowIndex++;
printRow++;
}
if (printRow < totalRow) {
int j = totalRow - printRow;
//处理空行
for (int k = 1; k < j; k++) {
SXSSFRow dataRowBlank = sheet.createRow(rowIndex);
for (int a = 0; a < properties.length; a++) {
SXSSFCell newCell = dataRowBlank.createCell(a);
//设置边框
newCell.setCellStyle(borderstyle);
}
rowIndex++;
}
}
//页尾
SXSSFRow endRow = sheet.createRow(rowIndex);
SXSSFCell pgaeCell = endRow.createCell(0);
pgaeCell.setCellValue("第" + page + "页");
pgaeCell.setCellStyle(centerCellStyle);
//合并单元格
sheet.addMergedRegion(new CellRangeAddress(rowIndex, rowIndex, 0, headers.length - 1));
//取消excel默认的自动分页,打印时将excel文件打印在pdf的一页中。
sheet.setAutobreaks(true);
}
项目引用
3.17
org.apache.poi
poi
${poi.version}
org.apache.poi
poi-examples
${poi.version}
org.apache.poi
poi-ooxml
${poi.version}
org.apache.poi
poi-ooxml-schemas
${poi.version}
org.apache.poi
poi-scratchpad
${poi.version}