|
|
|
|
package com.engine.jucailinkq.common.util.excel;
|
|
|
|
|
|
|
|
|
|
import com.engine.jucailinkq.common.util.DateUtil;
|
|
|
|
|
import org.apache.poi.hssf.usermodel.*;
|
|
|
|
|
import org.apache.poi.ss.usermodel.*;
|
|
|
|
|
import org.apache.poi.ss.util.CellRangeAddress;
|
|
|
|
|
import org.apache.poi.ss.util.CellRangeAddressList;
|
|
|
|
|
import org.apache.poi.xssf.usermodel.*;
|
|
|
|
|
|
|
|
|
|
import java.util.*;
|
|
|
|
|
|
|
|
|
|
import static org.apache.poi.hssf.usermodel.DVConstraint.createExplicitListConstraint;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @Author: sy
|
|
|
|
|
* @Description:
|
|
|
|
|
* @Date: 2024/6/5
|
|
|
|
|
**/
|
|
|
|
|
public class ExcelUtil {
|
|
|
|
|
|
|
|
|
|
public static XSSFWorkbook genWorkbookV2(List<List<Object>> rowList, String sheetName) {
|
|
|
|
|
XSSFWorkbook workbook = new XSSFWorkbook();
|
|
|
|
|
// 设置title样式
|
|
|
|
|
XSSFCellStyle titleCellStyle = workbook.createCellStyle();
|
|
|
|
|
XSSFFont titleFont = workbook.createFont();
|
|
|
|
|
titleFont.setBold(true);
|
|
|
|
|
titleFont.setFontName("仿宋");
|
|
|
|
|
titleFont.setFontHeightInPoints((short) 15);
|
|
|
|
|
titleCellStyle.setFont(titleFont);
|
|
|
|
|
titleCellStyle.setAlignment(HorizontalAlignment.CENTER);
|
|
|
|
|
titleCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());//背景色
|
|
|
|
|
titleCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
|
|
|
|
titleCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
|
|
|
|
|
titleCellStyle.setBorderLeft(BorderStyle.THIN);
|
|
|
|
|
titleCellStyle.setBorderRight(BorderStyle.THIN);
|
|
|
|
|
titleCellStyle.setBorderTop(BorderStyle.THIN);
|
|
|
|
|
titleCellStyle.setBorderBottom(BorderStyle.THIN);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 设置主体样式
|
|
|
|
|
XSSFCellStyle cellStyle = workbook.createCellStyle();
|
|
|
|
|
XSSFFont font = workbook.createFont();
|
|
|
|
|
font.setFontName("宋体");
|
|
|
|
|
font.setFontHeightInPoints((short) 10);// 设置字体大小
|
|
|
|
|
cellStyle.setFont(font);// 选择需要用到的字体格式
|
|
|
|
|
cellStyle.setWrapText(true);
|
|
|
|
|
cellStyle.setBorderLeft(BorderStyle.THIN);
|
|
|
|
|
cellStyle.setBorderRight(BorderStyle.THIN);
|
|
|
|
|
cellStyle.setBorderTop(BorderStyle.THIN);
|
|
|
|
|
cellStyle.setBorderBottom(BorderStyle.THIN);
|
|
|
|
|
|
|
|
|
|
XSSFSheet sheet = workbook.createSheet(sheetName);
|
|
|
|
|
//自适应宽度
|
|
|
|
|
sheet.autoSizeColumn(0, true);
|
|
|
|
|
//默认列宽
|
|
|
|
|
sheet.setDefaultColumnWidth(20);
|
|
|
|
|
//默认行高
|
|
|
|
|
sheet.setDefaultRowHeightInPoints(18);
|
|
|
|
|
//遍历设置列宽
|
|
|
|
|
List<Object> header = rowList.get(0);
|
|
|
|
|
for (int i = 0; i < header.size(); i++) {
|
|
|
|
|
sheet.setColumnWidth(i, Math.max(12, header.get(i).toString().length() * 4) * 256);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int rowIndex = 0; rowIndex < rowList.size(); rowIndex++) {
|
|
|
|
|
List<Object> infoList = rowList.get(rowIndex);
|
|
|
|
|
XSSFRow row = sheet.createRow(rowIndex);
|
|
|
|
|
float height = 18;
|
|
|
|
|
float finalHeight = 18;
|
|
|
|
|
|
|
|
|
|
for (int cellIndex = 0; cellIndex < infoList.size(); cellIndex++) {
|
|
|
|
|
XSSFCell cell = row.createCell(cellIndex);
|
|
|
|
|
if (rowIndex == 0) {
|
|
|
|
|
cell.setCellStyle(titleCellStyle);
|
|
|
|
|
} else {
|
|
|
|
|
cell.setCellStyle(cellStyle);
|
|
|
|
|
}
|
|
|
|
|
Object o = infoList.get(cellIndex);
|
|
|
|
|
if (o instanceof String) {
|
|
|
|
|
cell.setCellType(CellType.STRING);
|
|
|
|
|
cell.setCellValue(String.valueOf(o));
|
|
|
|
|
} else if (o instanceof Boolean) {
|
|
|
|
|
cell.setCellType(CellType.BOOLEAN);
|
|
|
|
|
cell.setCellValue(String.valueOf(o));
|
|
|
|
|
} else if (o instanceof Date) {
|
|
|
|
|
cell.setCellType(CellType.STRING);
|
|
|
|
|
cell.setCellValue(DateUtil.getFormatLocalDate((Date) o));
|
|
|
|
|
} else {
|
|
|
|
|
cell.setCellType(CellType.STRING);
|
|
|
|
|
cell.setCellValue(o == null ? "" : o.toString());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//判断是否要调整高度
|
|
|
|
|
int width = sheet.getColumnWidth(cellIndex) / 256;
|
|
|
|
|
finalHeight = getFinalHeight(o, width, finalHeight, height);
|
|
|
|
|
}
|
|
|
|
|
row.setHeightInPoints(finalHeight);
|
|
|
|
|
}
|
|
|
|
|
return workbook;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static XSSFWorkbook genWorkbookV2(List<List<Object>> rowList, String sheetName, String title, int titleCellNum) {
|
|
|
|
|
XSSFWorkbook workbook = new XSSFWorkbook();
|
|
|
|
|
// 设置title样式
|
|
|
|
|
XSSFCellStyle titleCellStyle = workbook.createCellStyle();
|
|
|
|
|
XSSFFont titleFont = workbook.createFont();
|
|
|
|
|
titleFont.setBold(true);
|
|
|
|
|
titleFont.setFontName("仿宋");
|
|
|
|
|
titleFont.setFontHeightInPoints((short) 15);
|
|
|
|
|
titleCellStyle.setFont(titleFont);
|
|
|
|
|
titleCellStyle.setAlignment(HorizontalAlignment.CENTER);
|
|
|
|
|
titleCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());//背景色
|
|
|
|
|
titleCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
|
|
|
|
titleCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
|
|
|
|
|
titleCellStyle.setBorderLeft(BorderStyle.THIN);
|
|
|
|
|
titleCellStyle.setBorderRight(BorderStyle.THIN);
|
|
|
|
|
titleCellStyle.setBorderTop(BorderStyle.THIN);
|
|
|
|
|
titleCellStyle.setBorderBottom(BorderStyle.THIN);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 设置主体样式
|
|
|
|
|
XSSFCellStyle cellStyle = workbook.createCellStyle();
|
|
|
|
|
XSSFFont font = workbook.createFont();
|
|
|
|
|
font.setFontName("宋体");
|
|
|
|
|
font.setFontHeightInPoints((short) 10);// 设置字体大小
|
|
|
|
|
cellStyle.setFont(font);// 选择需要用到的字体格式
|
|
|
|
|
cellStyle.setWrapText(true);
|
|
|
|
|
cellStyle.setBorderLeft(BorderStyle.THIN);
|
|
|
|
|
cellStyle.setBorderRight(BorderStyle.THIN);
|
|
|
|
|
cellStyle.setBorderTop(BorderStyle.THIN);
|
|
|
|
|
cellStyle.setBorderBottom(BorderStyle.THIN);
|
|
|
|
|
|
|
|
|
|
XSSFSheet sheet = workbook.createSheet(sheetName);
|
|
|
|
|
//自适应宽度
|
|
|
|
|
sheet.autoSizeColumn(0, true);
|
|
|
|
|
//默认列宽
|
|
|
|
|
sheet.setDefaultColumnWidth(20);
|
|
|
|
|
//默认行高
|
|
|
|
|
sheet.setDefaultRowHeightInPoints(18);
|
|
|
|
|
// 合并第一行的前titleCellNum个单元格
|
|
|
|
|
CellRangeAddress cellRangeAddress = new CellRangeAddress(0, 0, 0, titleCellNum - 1);
|
|
|
|
|
sheet.addMergedRegion(cellRangeAddress);
|
|
|
|
|
//遍历设置列宽
|
|
|
|
|
List<Object> header = rowList.get(0);
|
|
|
|
|
for (int i = 0; i < header.size(); i++) {
|
|
|
|
|
sheet.setColumnWidth(i, Math.max(12, header.get(i).toString().length() * 4) * 256);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int rowIndex = 0; rowIndex <= rowList.size(); rowIndex++) {
|
|
|
|
|
XSSFRow row = sheet.createRow(rowIndex);
|
|
|
|
|
float height = 18;
|
|
|
|
|
float finalHeight = 18;
|
|
|
|
|
|
|
|
|
|
if (rowIndex == 0) {
|
|
|
|
|
XSSFCell cell = row.createCell(0);
|
|
|
|
|
cell.setCellStyle(titleCellStyle);
|
|
|
|
|
cell.setCellType(CellType.STRING);
|
|
|
|
|
cell.setCellValue(title);
|
|
|
|
|
} else {
|
|
|
|
|
List<Object> infoList = rowList.get(rowIndex - 1);
|
|
|
|
|
for (int cellIndex = 0; cellIndex < infoList.size(); cellIndex++) {
|
|
|
|
|
XSSFCell cell = row.createCell(cellIndex);
|
|
|
|
|
if (rowIndex == 1) {
|
|
|
|
|
cell.setCellStyle(titleCellStyle);
|
|
|
|
|
} else {
|
|
|
|
|
cell.setCellStyle(cellStyle);
|
|
|
|
|
}
|
|
|
|
|
Object o = infoList.get(cellIndex);
|
|
|
|
|
if (o instanceof String) {
|
|
|
|
|
cell.setCellType(CellType.STRING);
|
|
|
|
|
cell.setCellValue(String.valueOf(o));
|
|
|
|
|
} else if (o instanceof Boolean) {
|
|
|
|
|
cell.setCellType(CellType.BOOLEAN);
|
|
|
|
|
cell.setCellValue(String.valueOf(o));
|
|
|
|
|
} else if (o instanceof Date) {
|
|
|
|
|
cell.setCellType(CellType.STRING);
|
|
|
|
|
cell.setCellValue(DateUtil.getFormatLocalDate((Date) o));
|
|
|
|
|
} else {
|
|
|
|
|
cell.setCellType(CellType.STRING);
|
|
|
|
|
cell.setCellValue(o == null ? "" : o.toString());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//判断是否要调整高度
|
|
|
|
|
int width = sheet.getColumnWidth(cellIndex) / 256;
|
|
|
|
|
finalHeight = getFinalHeight(o, width, finalHeight, height);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
row.setHeightInPoints(finalHeight);
|
|
|
|
|
}
|
|
|
|
|
return workbook;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static HSSFWorkbook genWorkbookV2WithDropdownList1(List<List<Object>> rowList, String sheetName, String title, int titleCellNum, String[] dropdownData, List<Integer> deopdownRange) {
|
|
|
|
|
HSSFWorkbook hssfWorkbook = new HSSFWorkbook();
|
|
|
|
|
// 设置title样式
|
|
|
|
|
HSSFCellStyle titleCellStyle = hssfWorkbook.createCellStyle();
|
|
|
|
|
HSSFFont titleFont = hssfWorkbook.createFont();
|
|
|
|
|
titleFont.setBold(true);
|
|
|
|
|
titleFont.setFontName("仿宋");
|
|
|
|
|
titleFont.setFontHeightInPoints((short) 15);
|
|
|
|
|
titleCellStyle.setFont(titleFont);
|
|
|
|
|
titleCellStyle.setAlignment(HorizontalAlignment.CENTER);
|
|
|
|
|
titleCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());//背景色
|
|
|
|
|
titleCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
|
|
|
|
titleCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
|
|
|
|
|
titleCellStyle.setBorderLeft(BorderStyle.THIN);
|
|
|
|
|
titleCellStyle.setBorderRight(BorderStyle.THIN);
|
|
|
|
|
titleCellStyle.setBorderTop(BorderStyle.THIN);
|
|
|
|
|
titleCellStyle.setBorderBottom(BorderStyle.THIN);
|
|
|
|
|
// 设置主体样式
|
|
|
|
|
HSSFCellStyle cellStyle = hssfWorkbook.createCellStyle();
|
|
|
|
|
HSSFFont font = hssfWorkbook.createFont();
|
|
|
|
|
font.setFontName("宋体");
|
|
|
|
|
font.setFontHeightInPoints((short) 10);// 设置字体大小
|
|
|
|
|
cellStyle.setFont(font);// 选择需要用到的字体格式
|
|
|
|
|
cellStyle.setWrapText(true);
|
|
|
|
|
cellStyle.setBorderLeft(BorderStyle.THIN);
|
|
|
|
|
cellStyle.setBorderRight(BorderStyle.THIN);
|
|
|
|
|
cellStyle.setBorderTop(BorderStyle.THIN);
|
|
|
|
|
cellStyle.setBorderBottom(BorderStyle.THIN);
|
|
|
|
|
|
|
|
|
|
HSSFSheet sheet = hssfWorkbook.createSheet(sheetName);
|
|
|
|
|
//自适应宽度
|
|
|
|
|
sheet.autoSizeColumn(0, true);
|
|
|
|
|
//默认列宽
|
|
|
|
|
sheet.setDefaultColumnWidth(20);
|
|
|
|
|
//默认行高
|
|
|
|
|
sheet.setDefaultRowHeightInPoints(18);
|
|
|
|
|
//设置下拉列表
|
|
|
|
|
Map<String, String> boxMap = new HashMap<>();
|
|
|
|
|
boxMap.put("班次名称", String.join(",", dropdownData));
|
|
|
|
|
//指定将下拉框添加至1-10行,0-0列。即第一列的第2到11行
|
|
|
|
|
HSSFDataValidation dataValidation = createBox("班次名称", boxMap , deopdownRange.get(0), deopdownRange.get(1), deopdownRange.get(2), deopdownRange.get(3));
|
|
|
|
|
if(dataValidation != null) {
|
|
|
|
|
sheet.addValidationData(dataValidation);
|
|
|
|
|
}
|
|
|
|
|
sheet.addValidationData(dataValidation);
|
|
|
|
|
// 合并第一行的前titleCellNum个单元格
|
|
|
|
|
CellRangeAddress cellRangeAddress = new CellRangeAddress(0, 0, 0, titleCellNum - 1);
|
|
|
|
|
sheet.addMergedRegion(cellRangeAddress);
|
|
|
|
|
//遍历设置列宽
|
|
|
|
|
List<Object> header = rowList.get(0);
|
|
|
|
|
for (int i = 0; i < header.size(); i++) {
|
|
|
|
|
sheet.setColumnWidth(i, Math.max(12, header.get(i).toString().length() * 4) * 256);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int rowIndex = 0; rowIndex <= rowList.size(); rowIndex++) {
|
|
|
|
|
HSSFRow row = sheet.createRow(rowIndex);
|
|
|
|
|
float height = 18;
|
|
|
|
|
float finalHeight = 18;
|
|
|
|
|
|
|
|
|
|
if (rowIndex == 0) {
|
|
|
|
|
HSSFCell cell = row.createCell(0);
|
|
|
|
|
cell.setCellStyle(titleCellStyle);
|
|
|
|
|
cell.setCellType(CellType.STRING);
|
|
|
|
|
cell.setCellValue(title);
|
|
|
|
|
} else {
|
|
|
|
|
List<Object> infoList = rowList.get(rowIndex - 1);
|
|
|
|
|
for (int cellIndex = 0; cellIndex < infoList.size(); cellIndex++) {
|
|
|
|
|
HSSFCell cell = row.createCell(cellIndex);
|
|
|
|
|
if (rowIndex == 1) {
|
|
|
|
|
cell.setCellStyle(titleCellStyle);
|
|
|
|
|
} else {
|
|
|
|
|
cell.setCellStyle(cellStyle);
|
|
|
|
|
}
|
|
|
|
|
Object o = infoList.get(cellIndex);
|
|
|
|
|
if (o instanceof String) {
|
|
|
|
|
cell.setCellType(CellType.STRING);
|
|
|
|
|
cell.setCellValue(String.valueOf(o));
|
|
|
|
|
} else if (o instanceof Boolean) {
|
|
|
|
|
cell.setCellType(CellType.BOOLEAN);
|
|
|
|
|
cell.setCellValue(String.valueOf(o));
|
|
|
|
|
} else if (o instanceof Date) {
|
|
|
|
|
cell.setCellType(CellType.STRING);
|
|
|
|
|
cell.setCellValue(DateUtil.getFormatLocalDate((Date) o));
|
|
|
|
|
} else {
|
|
|
|
|
cell.setCellType(CellType.STRING);
|
|
|
|
|
cell.setCellValue(o == null ? "" : o.toString());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//判断是否要调整高度
|
|
|
|
|
int width = sheet.getColumnWidth(cellIndex) / 256;
|
|
|
|
|
finalHeight = getFinalHeight(o, width, finalHeight, height);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
row.setHeightInPoints(finalHeight);
|
|
|
|
|
}
|
|
|
|
|
return hssfWorkbook;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* excel导出,有码值的数据使用下拉框展示。
|
|
|
|
|
* @param col 列名
|
|
|
|
|
* @param boxMap 码值集合
|
|
|
|
|
* @param firstRow 插入下拉框开始行号
|
|
|
|
|
* @param lastRow 插入下拉框结束行号
|
|
|
|
|
* @param firstCol 插入下拉框开始列号
|
|
|
|
|
* @param lastCol 插入下拉框结束行号
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
public static HSSFDataValidation createBox(String col, Map<String, String> boxMap, int firstRow, int lastRow, int firstCol, int lastCol) {
|
|
|
|
|
HSSFDataValidation dataValidation = null;
|
|
|
|
|
//查询码值表,如果长度超过255,则截取
|
|
|
|
|
String cols = "";
|
|
|
|
|
String completeCols = "";
|
|
|
|
|
if(null != boxMap.get(col)) {
|
|
|
|
|
cols = boxMap.get(col);
|
|
|
|
|
}
|
|
|
|
|
completeCols = cols;
|
|
|
|
|
if (cols.length() > 255) {
|
|
|
|
|
cols = cols.substring(0, 255);
|
|
|
|
|
}
|
|
|
|
|
//设置下拉框
|
|
|
|
|
if(cols.length() > 0) {
|
|
|
|
|
String[] str = cols.split(",");
|
|
|
|
|
if (completeCols.length() > 255) {
|
|
|
|
|
String[] completeStr = completeCols.split(",");
|
|
|
|
|
if (!completeStr[str.length - 1].equals(str[str.length - 1])) {
|
|
|
|
|
str = Arrays.copyOf(completeStr, str.length - 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//指定firstRow-lastRow行,firstCol-lastCol列为下拉框
|
|
|
|
|
CellRangeAddressList cas = new CellRangeAddressList(firstRow , lastRow , firstCol , lastCol);
|
|
|
|
|
//创建下拉数据列
|
|
|
|
|
DVConstraint dvConstraint = DVConstraint.createExplicitListConstraint(str);
|
|
|
|
|
//将下拉数据放入下拉框
|
|
|
|
|
dataValidation = new HSSFDataValidation(cas, dvConstraint);
|
|
|
|
|
}
|
|
|
|
|
return dataValidation;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static float getFinalHeight(Object o, int width, float finalHeight, float height) {
|
|
|
|
|
if (o != null && getStrlength(o.toString()) > width) {
|
|
|
|
|
float remainder = getStrlength(o.toString()) % width;
|
|
|
|
|
int multiple = getStrlength(o.toString()) / width;
|
|
|
|
|
int finalMultiple = remainder > 0 ? (multiple + 1) : multiple;
|
|
|
|
|
float compareHeight = height * finalMultiple;
|
|
|
|
|
finalHeight = Math.max(finalHeight, compareHeight);
|
|
|
|
|
}
|
|
|
|
|
return finalHeight;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static int getStrlength(String str) {
|
|
|
|
|
int strLength = 0;
|
|
|
|
|
String chinese = "[\u0391-\uFFE5]";
|
|
|
|
|
/* 获取字段值的长度,如果含中文字符,则每个中文字符长度为2,否则为1 */
|
|
|
|
|
for (int i = 0; i < str.length(); i++) {
|
|
|
|
|
/* 从字符串中获取一个字符 */
|
|
|
|
|
String temp = str.substring(i, i + 1);
|
|
|
|
|
/* 判断是否为中文字符 */
|
|
|
|
|
if (temp.matches(chinese)) {
|
|
|
|
|
/* 中文字符长度为2 */
|
|
|
|
|
strLength += 2;
|
|
|
|
|
} else {
|
|
|
|
|
/* 其他字符长度为1 */
|
|
|
|
|
strLength += 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return strLength;
|
|
|
|
|
}
|
|
|
|
|
}
|