You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

933 lines
36 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package com.dsideal.base.Util;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jfinal.kit.Kv;
import com.jfinal.kit.PathKit;
import com.jfinal.kit.PropKit;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.upload.UploadFile;
import org.apache.commons.lang.StringUtils;
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.ss.util.RegionUtil;
import org.apache.poi.xssf.usermodel.*;
import java.io.*;
import java.sql.ResultSetMetaData;
import java.util.*;
@SuppressWarnings("unchecked")
public class ExcelCommonUtil {
/**
* https://fireinwind.iteye.com/blog/2168655
* 功能通用的导出excel功能
* 作者:黄海
* 时间2018-12-12
*
* @param jo
*/
public static void export(List<Record> list, JSONObject jo, String fileName) {
Page<Record> _page = new Page<>();
_page.setList(list);
_page.setPageNumber(1);
_page.setPageSize(99999);
_page.setTotalPage(1);
_page.setTotalRow(list.size());
export(_page, jo, fileName);
}
public static void export(List<Record> list, JSONObject jo, String fileName, List<Integer> hiddenColumns) {
Page<Record> _page = new Page<>();
_page.setList(list);
_page.setPageNumber(1);
_page.setPageSize(99999);
_page.setTotalPage(1);
_page.setTotalRow(list.size());
export(_page, jo, fileName, hiddenColumns);
}
public static void export(Page<?> page, JSONObject jo, String fileName) {
export(page, jo, fileName, null);
}
public static void export(Page<?> page, JSONObject jo, String fileName, List<Integer> hiddenColumns) {
//标题
String title = jo.getString("title");
//是不是显示序号
String showNumber = jo.getString("showNumber");
//sheet名称
String sheetName = jo.getString("sheetName");
//标题高度
short titleHeight = (short) (jo.getInteger("titleHeight") * 20);
//每一行数据的高度
short rowHeight = (short) (jo.getInteger("rowHeight") * 20);
//列信息
JSONArray colInfo = jo.getJSONArray("colInfo");
if (showNumber != null) {
JSONObject addjo = new JSONObject();
addjo.put("show_column_name", "序号");
addjo.put("list_column_name", "Number");
addjo.put("width", 20);
colInfo.add(0, addjo);
List<Record> list = new ArrayList<>();
for (int i = 0; i < page.getList().size(); i++) {
Record record = (Record) page.getList().get(i);
record.set("Number", (i + 1));
list.add(record);
}
page = new Page(list, page.getPageNumber(), page.getPageSize(), page.getTotalPage(), page.getTotalRow());
}
HSSFWorkbook hssfWorkbook = new HSSFWorkbook();
HSSFSheet hssfSheet = hssfWorkbook.createSheet(sheetName);
int count = 0;
HSSFRow row = hssfSheet.createRow(count++);
HSSFCell cell;
//设置标题字体
Font fontTitle = hssfWorkbook.createFont();
fontTitle.setFontHeightInPoints((short) 18); //字体大小
fontTitle.setFontName("黑体"); //字体
CellStyle cellStyleTitle = hssfWorkbook.createCellStyle();
cellStyleTitle.setFont(fontTitle);
cellStyleTitle.setVerticalAlignment(VerticalAlignment.CENTER);
cellStyleTitle.setAlignment(HorizontalAlignment.CENTER);
cellStyleTitle.setFillForegroundColor(IndexedColors.LIME.getIndex());
cellStyleTitle.setWrapText(true);//设置自动换行
Cell cellTitle = row.createCell(0);
cellTitle.setCellStyle(cellStyleTitle);
cellTitle.setCellValue(title);// 设置标题内容
//合并前N列写上标题
CellRangeAddress region = new CellRangeAddress(0, 0, 0, colInfo.size() - 1);// 下标从0开始 起始行号,终止行号, 起始列号,终止列号
//在sheet里增加合并单元格
hssfSheet.addMergedRegion(region);
//设置标题的高度
row.setHeight(titleHeight);
Font txtFont = hssfWorkbook.createFont();
txtFont.setFontHeightInPoints((short) 14); //字体大小
txtFont.setFontName("宋体"); //字体
txtFont.setBold(true);
CellStyle cellStyleTxt = hssfWorkbook.createCellStyle();
cellStyleTxt.setFont(txtFont);
cellStyleTxt.setAlignment(HorizontalAlignment.CENTER);
cellStyleTxt.setFillForegroundColor(IndexedColors.LIME.getIndex());
cellStyleTxt.setWrapText(true);//设置自动换行
cellStyleTxt.setVerticalAlignment(VerticalAlignment.CENTER);
cellStyleTxt.setBorderBottom(BorderStyle.THIN); // 底部边框
cellStyleTxt.setBorderLeft(BorderStyle.THIN); // 左边边框
cellStyleTxt.setBorderRight(BorderStyle.THIN); // 右边边框
cellStyleTxt.setBorderTop(BorderStyle.THIN); // 上边边框
cellStyleTxt.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
cellStyleTxt.setFillPattern(FillPatternType.SOLID_FOREGROUND);
//写入表头
row = hssfSheet.createRow(count++);
for (int i = 0; i < colInfo.size(); i++) {
//创建传入进来的表头的个数
cell = row.createCell(i);
//表头的值就是传入进来的值
JSONObject jsonObject2 = colInfo.getJSONObject(i);
int width = jsonObject2.getInteger("width");
row.setHeight(rowHeight);
cell.setCellValue(jsonObject2.getString("show_column_name"));
cell.setCellStyle(cellStyleTxt);
//需要显示特殊颜色的话
if (jsonObject2.getBoolean("specialColor") != null) {
CellStyle style = hssfWorkbook.createCellStyle();
style.setFont(txtFont);
style.setAlignment(HorizontalAlignment.CENTER);
style.setFillForegroundColor(IndexedColors.LIME.getIndex());
style.setWrapText(true);//设置自动换行
style.setVerticalAlignment(VerticalAlignment.CENTER);
style.setBorderBottom(BorderStyle.THIN); // 底部边框
style.setBorderLeft(BorderStyle.THIN); // 左边边框
style.setBorderRight(BorderStyle.THIN); // 右边边框
style.setBorderTop(BorderStyle.THIN); // 上边边框
style.setFillForegroundColor(IndexedColors.AQUA.getIndex());
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
cell.setCellStyle(style);
}
//调转宽度
hssfSheet.setColumnWidth(i, 256 * width + 184);
}
//正文与表头不是一个颜色
txtFont = hssfWorkbook.createFont();
txtFont.setFontHeightInPoints((short) 14); //字体大小
txtFont.setFontName("宋体"); //字体
cellStyleTxt = hssfWorkbook.createCellStyle();
cellStyleTxt.setFont(txtFont);
cellStyleTxt.setAlignment(HorizontalAlignment.CENTER);
cellStyleTxt.setFillForegroundColor(IndexedColors.LIME.getIndex());
cellStyleTxt.setWrapText(true);//设置自动换行
cellStyleTxt.setVerticalAlignment(VerticalAlignment.CENTER);
cellStyleTxt.setBorderBottom(BorderStyle.THIN); // 底部边框
cellStyleTxt.setBorderLeft(BorderStyle.THIN); // 左边边框
cellStyleTxt.setBorderRight(BorderStyle.THIN); // 右边边框
cellStyleTxt.setBorderTop(BorderStyle.THIN); // 上边边框
//导出数据
for (int i = 0; i < page.getList().size(); i++) {
row = hssfSheet.createRow(count++);
Record record = (Record) page.getList().get(i);
for (int j = 0; j < colInfo.size(); j++) {
JSONObject jsonObject2 = colInfo.getJSONObject(j);
cell = row.createCell(j);
cell.setCellStyle(cellStyleTxt);
String v = record.getStr(jsonObject2.getString("list_column_name"));
if (jsonObject2.getBoolean("booleanConvert") != null) {
if (v.equals("1")) {
v = "是";
} else {
v = "否";
}
}
if (jsonObject2.getString("nullDefault") != null) {
if (v == null || v.length() == 0) {
v = jsonObject2.getString("nullDefault");
}
}
cell.setCellValue(v);
row.setHeight(rowHeight);
}
}
//处理隐藏列
if (null != hiddenColumns && hiddenColumns.size() > 0) {
for (Integer hiddenColumn : hiddenColumns) {
hssfSheet.setColumnHidden(hiddenColumn, true);
}
}
//生成文件
File file = new File(fileName);
try {
FileOutputStream fileOutputStreane = new FileOutputStream(file);
hssfWorkbook.write(fileOutputStreane);
fileOutputStreane.flush();
fileOutputStreane.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 功能检查是不是合法的xls文件
* 作者:黄海
* 时间2019-01-03
*
* @return
* @throws FileNotFoundException
*/
public static Workbook getWorkbook(FileInputStream in) throws IOException {
//尝试一下是不是有效的xls文件
Workbook wb = null;
boolean isValidExcel = false;
try {
wb = new HSSFWorkbook(in);
isValidExcel = true;
} finally {
if (!isValidExcel && wb != null) {
wb.close();
return null;
}
return wb;
}
}
/**
* 功能:添加一级的下拉框校验
* 作者:黄海
* 时间2020-05-09
*
* @param excelFile
* @param sheetName
* @param col
* @param subjects
* @throws IOException
*/
public static void addValidation(String excelFile, String sheetName, int col, String[] subjects) throws IOException {
FileInputStream fis = new FileInputStream(excelFile);
HSSFWorkbook workbook = new HSSFWorkbook(fis);
HSSFSheet sheet = workbook.getSheet(sheetName);
DataValidationHelper helper = sheet.getDataValidationHelper();
DataValidationConstraint constraint = helper.createExplicitListConstraint(subjects);
CellRangeAddressList addressList;
DataValidation dataValidation;
//产生限制条件
for (int i = 1; i < sheet.getLastRowNum(); i++) {
addressList = new CellRangeAddressList(i, i, col, col);
dataValidation = helper.createValidation(constraint, addressList);
sheet.addValidationData(dataValidation);
}
FileOutputStream stream = new FileOutputStream(excelFile);
workbook.write(stream);
stream.close();
}
/**
* 功能:获取指定单元格的值(字符串)
* 作者:黄海
* 时间2019-01-01
*
* @param cell
* @return
*/
public static String getStringValue(Cell cell) {
String value = "";
if (cell == null || cell.equals(null) || cell.getCellType() == CellType.BLANK) {
value = "";
} else {
//判断数据类型
switch (cell.getCellType()) {
case FORMULA:
try {
/*
* 此处判断使用公式生成的字符串有问题因为HSSFDateUtil.isCellDateFormatted(cell)判断过程中cell
* .getNumericCellValue();方法会抛出java.lang.NumberFormatException异常
*/
if (DateUtil.isCellDateFormatted(cell)) {
Date businessDateTime = cell.getDateCellValue();
Calendar cal = Calendar.getInstance();
cal.setTime(businessDateTime);
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH) + 1;
int date = cal.get(Calendar.DATE);
value = year + "-" + month + "-" + date;
break;
} else {
value = String.valueOf(cell.getNumericCellValue());
}
} catch (IllegalStateException e) {
value = String.valueOf(cell.getRichStringCellValue());
}
break;
case NUMERIC:
value = "" + cell.getNumericCellValue();
break;
case STRING:
value = cell.getStringCellValue();
break;
default:
break;
}
}
//先设置为字符串格式
//cell.setCellType(CellType.STRING);
//然后读取之
//value=cell.getStringCellValue().trim();
if (value.endsWith(".0")) {
value = value.substring(0, value.length() - 2);
}
return value;
}
/**
* 功能:检查是不是用于导入的模板
* 作者:黄海
* 时间2019-01-03
*
* @param wb
* @return
*/
public static Sheet getSheetByWorkbook(Workbook wb, int needCols, int ignoreRowCount) {
//实际列数
Sheet sheet1 = wb.getSheetAt(0);
int nowCols = sheet1.getRow(ignoreRowCount).getPhysicalNumberOfCells();
if (needCols > nowCols) {
return null;
}
return sheet1;
}
public static Sheet getSheetByWorkbook(Workbook wb) {
//实际列数
Sheet sheet1 = wb.getSheetAt(0);
return sheet1;
}
/**
* 功能:检查是不是有空值
* 作者:黄海
* 时间2019-01-03
*
* @param sheet1
* @return
*/
public static JSONObject checkHaveBlankError(Sheet sheet1, int ignoreRowCount, int nowCols, CellStyle redStyle, CellStyle whileStyle) {
JSONObject jo = new JSONObject();
int count = 0;
boolean Error = false;
//遍历每一行
for (Row row : sheet1) {
count++;
//放过行首
if (count < ignoreRowCount + 1) {
continue;
}
//如果当前行没有数据,跳出循环: 行首第一个单元格为空,即视为当前行及以下不再为有效区域!
if (row.getCell(0) == null || row.getCell(0).toString().equals("")) {
break;
}
for (int i = 0; i < nowCols; i++) {
Cell cell = row.getCell(i);
if (cell == null || cell.toString().equals("")) {
cell = row.createCell(i);
cell.setCellStyle(redStyle);
Error = true;
} else {
cell.setCellStyle(whileStyle);
}
}
}
jo.put("Error", Error);
jo.put("count", count - ignoreRowCount);
return jo;
}
/**
* 功能检查是不是合法的xls文件
* 作者:黄海
* 时间2019-01-04
*
* @return
*/
public static JSONObject IsValidXls(String templateXls, int needCols, int ignoreRowCount) throws IOException {
//返回结果
JSONObject jo = new JSONObject();
//检查是不是EXCEL文件
File excelFile = new File(templateXls); // 创建文件对象
if (!excelFile.exists()) {
jo.put("success", false);
jo.put("message", "文件不存在!!");
return jo;
}
if (!excelFile.getName().endsWith("xls")) {
jo.put("success", false);
jo.put("message", "只接收xls格式文件");
return jo;
}
FileInputStream in = new FileInputStream(excelFile); // 文件流
Workbook wb = ExcelCommonUtil.getWorkbook(in);
if (wb == null) {
jo.put("success", false);
jo.put("message", "不是EXCEL文件格式");
} else {
//检查是不是符合我们要求的模板
Sheet sheet1 = ExcelCommonUtil.getSheetByWorkbook(wb, needCols, ignoreRowCount);
if (sheet1 == null) {
jo.put("success", false);
jo.put("message", "不是符合要求的模板文件!");
} else {
jo.put("success", true);
jo.put("message", "是符合要求的模板文件!");
}
}
if (in != null) {
in.close();
}
if (wb != null) {
wb.close();
}
return jo;
}
/**
* 功能检查xls文件是不是存在空值
* 作者:黄海
* 时间2019-01-04
*
* @param templateXls
* @return
*/
public static JSONObject IsHaveBlank(String templateXls, int ignoreRowCount, int nowCols) throws IOException {
JSONObject jo = new JSONObject();
FileInputStream in = new FileInputStream(templateXls); // 文件流
Workbook wb = ExcelCommonUtil.getWorkbook(in);
//声明两个样式
CellStyle redStyle = ExcelCommonUtil.getCellStyle(wb, IndexedColors.RED.getIndex());
CellStyle whileStyle = ExcelCommonUtil.getCellStyle(wb);
Sheet sheet1 = wb.getSheetAt(0);
//检查一下行数
//检查是不是有为空的
JSONObject ErrorBlankJO = ExcelCommonUtil.checkHaveBlankError(sheet1, ignoreRowCount, nowCols, redStyle, whileStyle);
//存在不存在空的都回写一下
FileOutputStream excelFileOutPutStream = new FileOutputStream(templateXls);
wb.write(excelFileOutPutStream);
excelFileOutPutStream.flush();
//2、检查是不是都完整填写
if (ErrorBlankJO.getBoolean("Error")) {
jo.put("success", false);
jo.put("message", "发现有信息为空的列,不能继续,请检查后重新提交!");
} else {
if (ErrorBlankJO.getInteger("count") == 0) {
jo.put("success", false);
jo.put("message", "检查发现是一个空的表格,不能上传!");
} else {
jo.put("success", true);
jo.put("message", "检查通过,不存在空值的项!");
}
}
if (in != null) {
in.close();
}
if (wb != null) {
wb.close();
}
return jo;
}
/**
* 功能:获取样式
* 作者:黄海
* 时间2019-01-2
*
* @param wb
* @param color
* @return
*/
public static CellStyle getCellStyle(Workbook wb, short color) {
CellStyle style = getCellStyle(wb);
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
style.setFillForegroundColor(color);
return style;
}
/**
* 功能:获取样式
* 作者:黄海
* 时间2019-01-2
*
* @param wb
* @return
*/
public static CellStyle getCellStyle(Workbook wb) {
CellStyle style = wb.createCellStyle();
style.setAlignment(HorizontalAlignment.CENTER);
style.setWrapText(true);//设置自动换行
style.setVerticalAlignment(VerticalAlignment.CENTER);
style.setBorderBottom(BorderStyle.THIN); // 底部边框
style.setBorderLeft(BorderStyle.THIN); // 左边边框
style.setBorderRight(BorderStyle.THIN); // 右边边框
style.setBorderTop(BorderStyle.THIN); // 上边边框
Font txtFont = wb.createFont();
txtFont.setFontHeightInPoints((short) 14); //字体大小
txtFont.setFontName("宋体"); //字体
style.setFont(txtFont);
style.setFillForegroundColor(IndexedColors.LIME.getIndex());
//设置文本格式
DataFormat format = wb.createDataFormat();
style.setDataFormat(format.getFormat("@"));
return style;
}
public static Kv ImportExcelPublicCheckFunction(UploadFile picFile, int ignoreRowCount, int needCols, boolean checkBlank) throws IOException {
String fileName = picFile.getFileName();
Kv kv = Kv.create();
String suffix = fileName.substring(fileName.lastIndexOf(".") + 1).trim();
if (!suffix.equals("xls")) {
kv.set("success", false);
kv.set("message", "上传文件类型错误系统只允许上传xls格式");
return kv;
}
//判断文件大小大于20mb则返回错误信息并终止上传删除上传文件
long size = picFile.getFile().length();
if (size > 1024 * 1024 * 20) {
kv.set("success", false);
kv.set("message", "xls文件大小大于20MB,请检查!");
return kv;
}
String basePath = PathKit.getRootClassPath() + PropKit.get("ExcelImportTemplatePathSuffix").replace("\\", "/");
String TemplatePath = basePath + "excelTemp/";
String uuidString = UUID.randomUUID().toString().toUpperCase();
String templateXls = TemplatePath + "/" + uuidString + ".xls";
//判断目录是不是存在
File file = new File(TemplatePath);
if (!file.exists()) {
file.mkdirs();// 创建文件夹
}
picFile.getFile().renameTo(new File(templateXls));
//1、是不是XLS格式是不是我们的模板
JSONObject jo = ExcelCommonUtil.IsValidXls(templateXls, needCols, ignoreRowCount);
if (!jo.getBoolean("success")) {
kv.set("success", false);
return kv;
}
//2、检查一下是不是有空的
if (checkBlank) {
jo = ExcelCommonUtil.IsHaveBlank(templateXls, ignoreRowCount, needCols);
if (!jo.getBoolean("success")) {
kv.set("success", false);
return kv;
}
}
kv.set("uuid", uuidString);
kv.set("templateXls", templateXls);
kv.set("success", true);
return kv;
}
/**
* 功能导入EXCEL通用检查函数(允许空值)
* 作者:黄海
* 时间2019-08-11
*
* @param picFile
* @param ignoreRowCount
* @param needCols
* @return
* @throws IOException
*/
public static Kv ImportExcelPublicCheckFunctionAllowBlank(UploadFile picFile, int ignoreRowCount, int needCols) throws IOException {
String fileName = picFile.getFileName();
Kv kv = Kv.create();
String suffix = fileName.substring(fileName.lastIndexOf(".") + 1).trim();
if (!suffix.equals("xls")) {
kv.set("success", false);
kv.set("message", "上传文件类型错误系统只允许上传xls格式");
return kv;
}
//判断文件大小大于20mb则返回错误信息并终止上传删除上传文件
long size = picFile.getFile().length();
if (size > 1024 * 1024 * 20) {
kv.set("success", false);
kv.set("message", "xls文件大小大于20MB,请检查!");
return kv;
}
String basePath = PathKit.getRootClassPath() + PropKit.get("ExcelImportTemplatePathSuffix").replace("\\", "/");
String TemplatePath = basePath + "excelTemp/";
String uuidString = UUID.randomUUID().toString().toUpperCase();
String templateXls = TemplatePath + "/" + uuidString + ".xls";
//判断目录是不是存在
File file = new File(TemplatePath);
if (!file.exists()) {
file.mkdirs();// 创建文件夹
}
picFile.getFile().renameTo(new File(templateXls));
//1、是不是XLS格式是不是我们的模板
JSONObject jo = ExcelCommonUtil.IsValidXls(templateXls, needCols, ignoreRowCount);
if (!jo.getBoolean("success")) {
kv.set("success", false);
kv.set("message", jo.get("message"));
return kv;
}
kv.set("uuid", uuidString);
kv.set("templateXls", templateXls);
kv.set("success", true);
return kv;
}
/**
* 功能给定一个EXCEL的列名转换为数字
* 作者:黄海
* 时间2019-09-05
*
* @param colStr
* @return
*/
public static int excelColStrToNum(String colStr) {
int length = colStr.length();
int num;
int result = 0;
for (int i = 0; i < length; i++) {
char ch = colStr.charAt(length - i - 1);
num = ch - 'A' + 1;
num *= Math.pow(26, i);
result += num;
}
return result - 1;
}
/**
* 功能给定一个EXCEL的列序号返回列名
* 作者:黄海
* 时间2019-09-05
*
* @param columnIndex
* @return
*/
public static String excelColIndexToStr(int columnIndex) {
if (columnIndex <= 0) {
return null;
}
String columnStr = "";
columnIndex--;
do {
if (columnStr.length() > 0) {
columnIndex--;
}
columnStr = ((char) (columnIndex % 26 + (int) 'A')) + columnStr;
columnIndex = (columnIndex - columnIndex % 26) / 26;
} while (columnIndex > 0);
return columnStr;
}
/**
* 功能创建Xssf的颜色
* 作者:黄海
* 时间2019-09-26
*
* @param hex
* @return
*/
public static XSSFColor createXssfColor(String hex) {
String colorStr = hex;
if (hex.startsWith("#")) {
colorStr = hex.substring(1);
}
if (StringUtils.length(colorStr) == 8) {
colorStr = hex.substring(2);
}
int r = Integer.valueOf(colorStr.substring(0, 2), 16);
int g = Integer.valueOf(colorStr.substring(2, 4), 16);
int b = Integer.valueOf(colorStr.substring(4, 6), 16);
int[] rgbColor = new int[]{r, g, b};
XSSFColor xssfColor = new XSSFColor(new java.awt.Color(rgbColor[0], rgbColor[1], rgbColor[2]), new DefaultIndexedColorMap());
return xssfColor;
}
/**
* 功能:合并单元格成区域
* 作者:黄海
* 时间2019-09-28
*
* @param sheet
* @param firstCol
* @param lastCol
*/
public static void MergeRegion(XSSFSheet sheet, int first_row, int last_row, int firstCol, int lastCol) {
CellRangeAddress region = new CellRangeAddress(first_row, last_row, firstCol, lastCol);
sheet.addMergedRegion(region);
//边框
RegionUtil.setBorderBottom(BorderStyle.THIN, region, sheet);
RegionUtil.setBorderLeft(BorderStyle.THIN, region, sheet);
RegionUtil.setBorderRight(BorderStyle.THIN, region, sheet);
RegionUtil.setBorderTop(BorderStyle.THIN, region, sheet);
}
/**
* 功能:合并单元格(相同单元格内容)
* 作者:黄海
* 时间2019-09-25
*
* @param size
* @param cellStyle
* @param sheet
* @param col
*/
public static List<Record> mergeCellBySameContent(int size, int startRow, CellStyle cellStyle, Sheet sheet, int col) {
List<Record> Mergelist = new ArrayList<>();
int totalRow = size + startRow;
for (int p = startRow; p < totalRow; p++) {// totalRow 总行数
Cell currentCell = sheet.getRow(p).getCell(col);
String current = ExcelCommonUtil.getStringValue(currentCell);
Cell nextCell;
String next = "";
if (p < totalRow + 1) {
Row nowRow = sheet.getRow(p + 1);
if (nowRow != null) {
nextCell = nowRow.getCell(col);
next = ExcelCommonUtil.getStringValue(nextCell);
} else {
next = "";
}
} else {
next = "";
}
if (current.equals(next)) {// 比对是否相同
currentCell.setCellValue("");
continue;
} else if (!current.equals(next)) {
if ((p) - startRow > 0 && current != "") {
sheet.addMergedRegion(new CellRangeAddress(startRow, p, col, col));// 合并单元格
Record record = new Record();
record.set("firstRow", startRow);
record.set("lastRow", p);
Mergelist.add(record);
Cell nowCell = sheet.getRow(startRow).getCell(col);
nowCell.setCellValue(current);
nowCell.setCellStyle(cellStyle);
}
startRow = p + 1;
}
}
return Mergelist;
}
/**
* 功能获取一个黄海常用的EXCEL中单元格的样式
* 作者:黄海
* 时间2019-09-27
*
* @param workbook
* @return
*/
public static XSSFCellStyle GenerateNormalCellStyle(XSSFWorkbook workbook, String fontName, int fontSize) {
//主表格的样式
Font txtFont = workbook.createFont();
txtFont.setFontHeightInPoints((short) fontSize); //字体大小
txtFont.setFontName(fontName); //字体
txtFont.setBold(false);
XSSFCellStyle cellStyleTxt = workbook.createCellStyle();
cellStyleTxt.setFont(txtFont);
cellStyleTxt.setAlignment(HorizontalAlignment.CENTER);
cellStyleTxt.setWrapText(true);//设置自动换行
cellStyleTxt.setVerticalAlignment(VerticalAlignment.CENTER);
cellStyleTxt.setBorderBottom(BorderStyle.THIN); // 底部边框
cellStyleTxt.setBorderLeft(BorderStyle.THIN); // 左边边框
cellStyleTxt.setBorderRight(BorderStyle.THIN); // 右边边框
cellStyleTxt.setBorderTop(BorderStyle.THIN); // 上边边框
return cellStyleTxt;
}
/**
* 功能:从一个标准的单元格样式复制出来一个背景色特殊的样式
* 作者:黄海
* 时间2019-09-28
*
* @param workbook
* @param sourceCellStyle
* @param hexColor
* @return
*/
public static XSSFCellStyle CopyColorCellStyle(XSSFWorkbook workbook,
XSSFCellStyle sourceCellStyle, String hexColor) {
XSSFCellStyle style = workbook.createCellStyle();
style.cloneStyleFrom(sourceCellStyle);
style.setFillPattern(FillPatternType.SOLID_FOREGROUND); //设置填充方案
style.setFillForegroundColor(ExcelCommonUtil.createXssfColor(hexColor)); //设置填充颜色
return style;
}
/**
* 功能:移除合并好的单元格
* 作者:黄海
* 时间2019-09-27
*
* @param sheet
* @param row
* @param column
*/
public static void removeMergedRegion(XSSFSheet sheet, int row, int column) {
int sheetMergeCount = sheet.getNumMergedRegions();//获取所有的单元格
int index = 0;//用于保存要移除的那个单元格序号
for (int i = 0; i < sheetMergeCount; i++) {
CellRangeAddress ca = sheet.getMergedRegion(i); //获取第i个单元格
int firstColumn = ca.getFirstColumn();
int lastColumn = ca.getLastColumn();
int firstRow = ca.getFirstRow();
int lastRow = ca.getLastRow();
if (row >= firstRow && row <= lastRow) {
if (column >= firstColumn && column <= lastColumn) {
index = i;
}
}
}
sheet.removeMergedRegion(index);//移除合并单元格
}
/**
* 将List<Record>数据写入到Excel中
*
* @param tableData
* @param filePath
* @throws IOException
*/
public static void writeExcel(List<Record> tableData, String filePath, boolean killIdColumns) throws IOException {
if (killIdColumns) {
//表tableData中如果有一列叫id,那么去掉这一列
for (Record tableDatum : tableData) {
tableDatum.remove("id");
}
}
// 创建Excel工作簿
Workbook workbook = new XSSFWorkbook();
// 创建一个Excel工作表
Sheet sheet = workbook.createSheet("Sheet1");
// 获取第一个Record的元数据以确定列名
int columnCount = tableData.getFirst().size();
// 创建标题行
Row titleRow = sheet.createRow(0);
// 设置标题行的样式
CellStyle titleStyle = workbook.createCellStyle();
Font font = workbook.createFont();
font.setBold(true);
font.setFontHeightInPoints((short) 14);
titleStyle.setFont(font);
titleStyle.setBorderBottom(BorderStyle.THIN);
titleStyle.setBorderLeft(BorderStyle.THIN);
titleStyle.setBorderRight(BorderStyle.THIN);
titleStyle.setBorderTop(BorderStyle.THIN);
// 填充标题行
for (int i = 1; i <= columnCount; i++) {
Cell cell = titleRow.createCell(i - 1);
cell.setCellValue(tableData.getFirst().getColumnNames()[i - 1]);
cell.setCellStyle(titleStyle);
}
// 创建数据行的样式
CellStyle dataStyle = workbook.createCellStyle();
font = workbook.createFont();
font.setFontHeightInPoints((short) 14);
dataStyle.setFont(font);
dataStyle.setBorderBottom(BorderStyle.THIN);
dataStyle.setBorderLeft(BorderStyle.THIN);
dataStyle.setBorderRight(BorderStyle.THIN);
dataStyle.setBorderTop(BorderStyle.THIN);
// 填充数据行
int rowNum = 1;
for (Record record : tableData) {
Row row = sheet.createRow(rowNum++);
int cellNum = 0;
for (int i = 1; i <= columnCount; i++) {
Cell cell = row.createCell(cellNum++);
Object value = record.get(tableData.getFirst().getColumnNames()[i - 1]);
cell.setCellValue(value == null ? "" : value.toString());
cell.setCellStyle(dataStyle);
}
}
// 设置最小列宽
int minColumnWidth = 100 * 256 / 7; // 将像素转换为字符单位Excel的单位是1/256个字符宽度
for (int i = 0; i < tableData.getFirst().getColumnNames().length; i++) {
sheet.setColumnWidth(i, Math.max(minColumnWidth, sheet.getColumnWidth(i)));
}
// 自动调整列宽
for (int i = 0; i < tableData.getFirst().getColumnNames().length; i++) {
sheet.autoSizeColumn(i);
int columnWidth = sheet.getColumnWidth(i);
int newColumnWidth = Math.max(minColumnWidth, columnWidth);
sheet.setColumnWidth(i, newColumnWidth);
}
// 将工作簿写入文件
try (FileOutputStream fileOut = new FileOutputStream(filePath)) {
workbook.write(fileOut);
}
// 关闭工作簿
workbook.close();
}
}