摘要
本文主要讲解了POI中的表格行高列宽比例,以及根据这个不同的场景生成,如标题,说明,字段头。主要是思路给大家参考,生成表格如下(完整代码代码在最后,由于我的数据格式特殊,我把我以前的通用导出数据代码放在了数据行导出)
目录
目录
比例讲解
行高
行高的设置方法常用的是
row.setHeight (heght)
他们之间的比例近似于1:20,例如,Excel中的50磅(100像素),代码中应该写为
row.setHeight((short) (50*20));
列宽
列宽的设置方法为
sheet.setColumnWidth(cellNum, weight);
他们之间的公式大致为(weight+0.7)*256,例如,Excel中的50磅(100像素),代码中应该写为
sheet.setColumnWidth(cellNum, (int) ((50 + 0.72) * 256));
代码
生成填写说明
他的行高调整 noteDatas.size() * (30*20) //说明总行数*(单行高度*比例)
/**
* 生成第一行数据(填写说明)
* @param regionNumber 合并单元格个数
* @param noteDatas 说明数据
* @param workbook 工作薄
* @param sheet sheet
* @autor whhhh
*/
private static void addDetailRow(Integer regionNumber, List<String> noteDatas, HSSFWorkbook workbook, HSSFSheet sheet) {
// 创建提示行(第一行)
HSSFRow rowDetail = sheet.createRow(0);
//转换成字符串
StringBuilder noted= new StringBuilder();
int keyNum=1;
//遍历添加每一行加序号 \r\n用来换行
for(String fileNote:noteDatas){
noted.append(keyNum).append(". ").append(fileNote).append("\r\n");
keyNum++;
}
//生成表格数据
HSSFRichTextString ts = new HSSFRichTextString("填写说明\r\n"+noted);
//设置部分字体加粗
HSSFFont noteFont = workbook.createFont();
noteFont.setBold(true);
noteFont.setFontHeightInPoints((short) 14);
ts.applyFont(0, 4, noteFont);
//添加内容
rowDetail.createCell(0).setCellValue(ts);
//设置标题字体样式
HSSFCellStyle detailStyle = workbook.createCellStyle();
detailStyle.setAlignment(HorizontalAlignment.LEFT);//水平居左
detailStyle.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中
HSSFFont detailFont = workbook.createFont();
detailFont.setFontName("宋体");//字体
detailFont.setFontHeightInPoints((short) 12);//字体大小
detailStyle.setFont(detailFont);
detailStyle.setWrapText(true);
//合并单元格
CellRangeAddress region1 = new CellRangeAddress(0, 0, 0, regionNumber);
sheet.addMergedRegion(region1);
//设置当前行样式
rowDetail.getCell(0).setCellStyle(detailStyle);//把样式加入该行
short detailHeight= (short) (noteDatas.size() * (30*20));//说明行数*(单行高度*比例)
rowDetail.setHeight(detailHeight);//设置行高
}
生成标题行
/**
* 生成第二行数据(文件标题)
* @param reginNumber 所占单元格个数
* @param title 标题
* @param workbook 工作薄
* @param sheet sheet
* @autor whhhh
*/
private static void addTitleRow(Integer reginNumber,String title, HSSFWorkbook workbook, HSSFSheet sheet) {
// 创建标题行(第二行)存入标题
HSSFRow rowTitle = sheet.createRow(1);
rowTitle.createCell(0).setCellValue(title);
//设置标题字体样式
HSSFCellStyle titleStyle = workbook.createCellStyle();
titleStyle.setAlignment(HorizontalAlignment.CENTER);//水平居中
titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中
HSSFFont titleFont = workbook.createFont();
titleFont.setFontName("方正小标宋_GBK");//字体
titleFont.setFontHeightInPoints((short) 22);//字体大小
titleStyle.setFont(titleFont);
rowTitle.getCell(0).setCellStyle(titleStyle);
rowTitle.setHeight((short) (50*20));
//合并单元格
CellRangeAddress region2 = new CellRangeAddress(1, 1, 0, reginNumber);
sheet.addMergedRegion(region2);
}
生成字段头
/**
* 生成第三行数据(表头)
* @param excelHeads 表头
* @param workbook 工作薄
* @param sheet sheet
* @autor whhhh
*/
private static void addExcelHead(List<String> excelHeads, HSSFWorkbook workbook, HSSFSheet sheet) {
//创建表头(第三行)
HSSFRow row = sheet.createRow(2);
//定义循环变量
int cellNum=1;
//设置字段头字体样式
HSSFCellStyle headStyle = workbook.createCellStyle();
HSSFFont headFont = workbook.createFont();
headFont.setFontName("黑体");
headFont.setFontHeightInPoints((short) 13);
headStyle.setFont(headFont);
headStyle.setAlignment(HorizontalAlignment.CENTER);
//生成序号列 并设置样式
row.createCell(0).setCellValue("序号");
row.getCell(0).setCellStyle(headStyle);
//生成表头数据并设置样式
for (String excelHead:excelHeads) {
row.createCell(cellNum).setCellValue(excelHead);
row.getCell(cellNum).setCellStyle(headStyle);
//设置表格单元格长度
if(excelHead.contains("地址")) {
//地址栏内容一般偏多,设置稍大点
sheet.setColumnWidth(cellNum, (int) ((50 + 0.71) * 256));
}else {
sheet.setColumnWidth(cellNum, (int) ((20 + 0.71) * 256));
}
cellNum++;
}
}
数据行导出
由于我的数据行格式特殊,我把我以前的导出数据放在这里
/**
* 输出Excel
* @param dataList 数据集合
* @param resp 响应
* @throws CustomerException 自定义异常
* @throws IOException io异常
* @Auther: whhh
* @Date: 2021/4/15 11:44
*/
public static void exportList(List<Map<String,Object>> dataList, HttpServletResponse resp,String fileName) throws CustomerException, IOException {
if (CollectionUtils.isEmpty(dataList)){
return;
}
//2.创建XSSFWorkbook
XSSFWorkbook workbook=new XSSFWorkbook();
//3.创建sheet对象
XSSFSheet sheet = workbook.createSheet();
//4.创建表头
XSSFRow row=sheet.createRow(0);
int m=0; //定义循环变量
//写入表头数据
for(String key:dataList.get(0).keySet()){
row.createCell(m).setCellValue(key);
m++;
}
//遍历集合,填充每一行的数据
for(int i=0;i< dataList.size();i++){
m=0; //重置循环变量
//获取当前数据行
Map<String,Object> data=dataList.get(i);
//创建当前行
XSSFRow r = sheet.createRow(i+1);
//存储数据
for(String key:data.keySet()){
r.createCell(m).setCellValue(data.get(key).toString());
m++;
}
}
fileName=UUID.randomUUID()+".xlsx";
//6.告诉浏览器以下载的方式打开
resp.setHeader("Content-Disposition","attachment;filename="+URLEncoder.encode(fileName,"UTF-8"));
//7.把数据写出到浏览器
OutputStream out = resp.getOutputStream();
workbook.write(out);
}
由于我的数据行格式特殊,我把我以前的导出数据放上面 ↑↑↑↑
整代码
由于我的数据行格式特殊,我把我以前的导出数据代码放上面 ↑↑↑↑
我这里是生成一个目录,里面放了一张excel和图片进行压缩
private void downloadZip(HttpServletResponse resp, List<Map<String, Object>> records, List<String> excelHeads, List<Integer> excelHeadsIds, CategoryDataVo categoryDataVo) {
try {
SimpleDateFormat df=new SimpleDateFormat("yyyyMMdd");
//在当前目录生成根文件夹
File temDir = new File(categoryDataVo.getFileName() + df.format(new Date()));
if (!temDir.exists()) {
temDir.mkdirs();
}
String zipName = categoryDataVo.getFileName() + ".zip";
//生成表格
downloadExcel(records, excelHeads, excelHeadsIds, temDir,categoryDataVo);
//告诉浏览器以下载的方式打开zip
resp.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(zipName, "UTF-8"));
resp.setContentType("application/zip");
//压缩文件
ZipFilesUtil.toZip(temDir.getPath(), resp.getOutputStream(),true);
temDir.delete();
}catch (CustomerException e){
e.printStackTrace();
throw new CustomerException(MessageCode.IMAGE_DOWNLOAD_FAIL);
}catch (Exception e){
e.printStackTrace();
throw new CustomerException(MessageCode.EXCEL_DOWNLOAD_FAIL);
}
}
/**
* 导出数据表格
* @param data 数据
* @param excelHeads 数据字段头
* @param excelHeadIds 数据字段头id
* @param temDir 根目录
* @param categoryDataVo 分类提示 代码在最后
* @autor whhhh
*/
public static void downloadExcel(List<Map<String, Object>> data, List<String> excelHeads, List<Integer> excelHeadIds,File temDir,CategoryDataVo categoryDataVo) {
try {
//生成excel文件
String excelName="/"+categoryDataVo.getFileName()+".xls";
File excel = new File(temDir + excelName);
//创建Workbook和Sheet文档
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = workbook.createSheet("sheet1");
// 创建提示行(第一行)
addDetailRow(excelHeads.size(), categoryDataVo.getNoteDatas(), workbook, sheet);
// 创建标题行(第二行)存入数据
addTitleRow(excelHeads.size(), categoryDataVo.getFileName(), workbook, sheet);
//创建表头(第三行)
addExcelHead(excelHeads, workbook, sheet);
//定义单元格循环变量
int cellNum;
//这里的数据行第四行起
int rowNum=3;
//设置数据样式
HSSFCellStyle cellStyle=workbook.createCellStyle();
cellStyle.setWrapText(true);//自动换行
cellStyle.setAlignment(HorizontalAlignment.CENTER);
cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
//添加数据行字体
HSSFFont cellFont = workbook.createFont();
cellFont.setFontName("宋体");//字体
cellFont.setFontHeightInPoints((short) 11);
cellStyle.setFont(cellFont);
//获取数据
for (Map<String, Object> map:data) {
//取出当前行数据
JSONObject extData = (JSONObject) map.get("extData");
// JSONArray images = (JSONArray) extData.get("images");
if (extData!=null){
cellNum=1;
//创建数据行
HSSFRow dataRow = sheet.createRow(rowNum);
dataRow.createCell(0).setCellValue(rowNum-2);
dataRow.getCell(0).setCellStyle(cellStyle);
for (Integer id:excelHeadIds) {
//取出数据
if(extData.get(id.toString())!=null) {
String rowdata = extData.get(id.toString()).toString();
if(rowdata!=null){
dataRow.createCell(cellNum).setCellValue(rowdata);
dataRow.getCell(cellNum).setCellStyle(cellStyle);
}
}
cellNum++;
}
rowNum++;
}
}
//把表格数据写出到目录路径
FileOutputStream excelOut = new FileOutputStream(excel);
workbook.write(excelOut);
excelOut.close();
}catch (CustomerException e){
e.printStackTrace();
throw new CustomerException(MessageCode.IMAGE_DOWNLOAD_FAIL);
}catch (Exception e){
e.printStackTrace();
throw new CustomerException(MessageCode.EXCEL_DOWNLOAD_FAIL);
}
}
/**
* 生成第一行数据(填写说明)
* @param regionNumber 合并单元格个数
* @param noteDatas 说明数据
* @param workbook 工作薄
* @param sheet sheet
* @autor whhhh
*/
private static void addDetailRow(Integer regionNumber, List<FileNote> noteDatas, HSSFWorkbook workbook, HSSFSheet sheet) {
// 创建提示行(第一行)
HSSFRow rowDetail = sheet.createRow(0);
//转换成字符串
StringBuilder noted= new StringBuilder();
int keyNum=1;
//遍历添加每一行加序号
for(FileNote fileNote:noteDatas){
noted.append(keyNum).append(". ").append(fileNote.getData()).append("\r\n");
keyNum++;
}
//生成表格数据
HSSFRichTextString ts = new HSSFRichTextString("填写说明\r\n"+noted);
//设置部分字体加粗
HSSFFont noteFont = workbook.createFont();
noteFont.setBold(true);
noteFont.setFontHeightInPoints((short) 14);
ts.applyFont(0, 4, noteFont);
//添加内容
rowDetail.createCell(0).setCellValue(ts);
//设置标题字体样式
HSSFCellStyle detailStyle = workbook.createCellStyle();
detailStyle.setAlignment(HorizontalAlignment.LEFT);//水平居左
detailStyle.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中
HSSFFont detailFont = workbook.createFont();
detailFont.setFontName("宋体");//字体
detailFont.setFontHeightInPoints((short) 12);//字体大小
detailStyle.setFont(detailFont);
detailStyle.setWrapText(true);
//合并单元格
CellRangeAddress region1 = new CellRangeAddress(0, 0, 0, regionNumber);
sheet.addMergedRegion(region1);
rowDetail.getCell(0).setCellStyle(detailStyle);//把样式加入该行
short detailHeight= (short) (noteDatas.size() * (20*20));//说明行数*(单行高度*比例)
rowDetail.setHeight(detailHeight);//设置行高
}
/**
* 生成第二行数据(文件标题)
* @param reginNumber 所占单元格个数
* @param title 标题
* @param workbook 工作薄
* @param sheet sheet
* @autor whhhh
*/
private static void addTitleRow(Integer reginNumber,String title, HSSFWorkbook workbook, HSSFSheet sheet) {
// 创建标题行(第二行)存入标题
HSSFRow rowTitle = sheet.createRow(1);
rowTitle.createCell(0).setCellValue(title);
//设置标题字体样式
HSSFCellStyle titleStyle = workbook.createCellStyle();
titleStyle.setAlignment(HorizontalAlignment.CENTER);//水平居中
titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中
HSSFFont titleFont = workbook.createFont();
titleFont.setFontName("方正小标宋_GBK");//字体
titleFont.setFontHeightInPoints((short) 22);//字体大小
titleStyle.setFont(titleFont);
rowTitle.getCell(0).setCellStyle(titleStyle);
rowTitle.setHeight((short) (50*20));
//合并单元格
CellRangeAddress region2 = new CellRangeAddress(1, 1, 0, reginNumber);
sheet.addMergedRegion(region2);
}
/**
* 生成第三行数据(表头)
* @param excelHeads 表头
* @param workbook 工作薄
* @param sheet sheet
* @autor whhhh
*/
private static void addExcelHead(List<String> excelHeads, HSSFWorkbook workbook, HSSFSheet sheet) {
//创建表头(第三行)
HSSFRow row = sheet.createRow(2);
//定义循环变量
int cellNum=1;
//设置字段头字体样式
HSSFCellStyle headStyle = workbook.createCellStyle();
HSSFFont headFont = workbook.createFont();
headFont.setFontName("黑体");
headFont.setFontHeightInPoints((short) 13);
headStyle.setFont(headFont);
headStyle.setAlignment(HorizontalAlignment.CENTER);
//生成序号列 并设置样式
row.createCell(0).setCellValue("序号");
row.getCell(0).setCellStyle(headStyle);
//生成表头数据并设置样式
for (String excelHead:excelHeads) {
row.createCell(cellNum).setCellValue(excelHead);
row.getCell(cellNum).setCellStyle(headStyle);
//设置表格单元格长度
if(excelHead.contains("地址")) {
//地址栏内容一般偏多,设置稍大点
sheet.setColumnWidth(cellNum, (int) ((50 + 0.71) * 256));
}else {
sheet.setColumnWidth(cellNum, (int) ((20 + 0.71) * 256));
}
cellNum++;
}
}
CategoryDataVo 类
package com.glzt.standingBookManagement.dto.vo;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.glzt.standingBookManagement.dao.FileNoteDao;
import com.glzt.standingBookManagement.dto.entity.FileNote;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
/**
* @Auther: whhh
* @Date: 2021/5/13 17:58
* @Description:
*/
@Data
public class CategoryDataVo {
@Autowired
private FileNoteDao fileNoteDao;
public static final String SPECIAL= "成都市大气污染防控专项督查工作问题台账";
public static final String MUNICIPAL= "成都大气污染防控专项督查工作市级部门自查台账";
public static final String COUNTY= "成都大气污染防控专项督查工作区县自查台账";
private String fileName;
private List<FileNote> noteDatas;
}