添加模板导入-可下拉选择
This commit is contained in:
@@ -0,0 +1,26 @@
|
|||||||
|
package com.njcn.common.pojo.poi;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author caozehui 设置下拉
|
||||||
|
* @description
|
||||||
|
* @date 2025-01-15
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class PullDown {
|
||||||
|
|
||||||
|
//起始列
|
||||||
|
private Integer firstCol;
|
||||||
|
|
||||||
|
//结束列
|
||||||
|
private Integer lastCol;
|
||||||
|
|
||||||
|
//是否设置单元格(文本)
|
||||||
|
private Boolean isText = false;
|
||||||
|
|
||||||
|
//属性值
|
||||||
|
private List<String> strings;
|
||||||
|
}
|
||||||
@@ -3,11 +3,16 @@ package com.njcn.web.utils;
|
|||||||
import cn.afterturn.easypoi.excel.ExcelExportUtil;
|
import cn.afterturn.easypoi.excel.ExcelExportUtil;
|
||||||
import cn.afterturn.easypoi.excel.entity.ExportParams;
|
import cn.afterturn.easypoi.excel.entity.ExportParams;
|
||||||
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
|
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.util.CharsetUtil;
|
import cn.hutool.core.util.CharsetUtil;
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import com.njcn.common.pojo.poi.PullDown;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||||
import org.apache.poi.ss.usermodel.Workbook;
|
import org.apache.poi.ss.usermodel.*;
|
||||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
import org.apache.poi.ss.util.CellRangeAddressList;
|
||||||
|
import org.apache.poi.ss.util.CellReference;
|
||||||
|
import org.apache.poi.xssf.usermodel.*;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import javax.servlet.ServletOutputStream;
|
import javax.servlet.ServletOutputStream;
|
||||||
@@ -18,6 +23,7 @@ import java.net.URLEncoder;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author caozehui
|
* @author caozehui
|
||||||
@@ -87,6 +93,229 @@ public class ExcelUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指定名称、数据下载报表(带指定标题将*显示比必填信息),带有下拉信息
|
||||||
|
*
|
||||||
|
* @param fileName 文件名
|
||||||
|
*/
|
||||||
|
public static void exportExcelPullDown(ExportParams exportParams, String fileName, List<PullDown> pullDowns, Class<?> pojoClass, Collection<?> dataSet) {
|
||||||
|
HttpServletResponse response = HttpServletUtil.getResponse();
|
||||||
|
try (ServletOutputStream outputStream = response.getOutputStream()) {
|
||||||
|
fileName = URLEncoder.encode(fileName, CharsetUtil.UTF_8);
|
||||||
|
response.reset();
|
||||||
|
response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
|
||||||
|
response.setContentType("application/octet-stream;charset=UTF-8");
|
||||||
|
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, pojoClass, dataSet);
|
||||||
|
setTopLevel(workbook, pullDowns);
|
||||||
|
if (CollUtil.isNotEmpty(pullDowns)) {
|
||||||
|
int num = 1;
|
||||||
|
CellStyle cellStyle = workbook.createCellStyle();
|
||||||
|
DataFormat format = workbook.createDataFormat();
|
||||||
|
cellStyle.setDataFormat(format.getFormat("@"));
|
||||||
|
for (PullDown pullDown : pullDowns) {
|
||||||
|
if (pullDown.getIsText()) {
|
||||||
|
ExcelUtil.selectListText(workbook, pullDown.getFirstCol(),cellStyle);
|
||||||
|
} else {
|
||||||
|
String colName = numberToExcelColumn(num);
|
||||||
|
int sum = pullDown.getStrings().stream().mapToInt(String::length).sum();
|
||||||
|
if (sum == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (sum > 255) {
|
||||||
|
ExcelUtil.selectListMaxLength(workbook, pullDown.getFirstCol(), pullDown.getLastCol(), pullDown.getStrings().size(), colName);
|
||||||
|
num++;
|
||||||
|
} else {
|
||||||
|
ExcelUtil.selectList(workbook, pullDown.getFirstCol(), pullDown.getLastCol(), pullDown.getStrings().toArray(new String[]{}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Sheet sheetAt = workbook.getSheetAt(0);
|
||||||
|
//获取列数
|
||||||
|
int physicalNumberOfCells = sheetAt.getRow(0).getPhysicalNumberOfCells();
|
||||||
|
//没有表格标题,只有表格头
|
||||||
|
for (int i = 0; i < 1; i++) {
|
||||||
|
//获取行
|
||||||
|
Row row = sheetAt.getRow(i);
|
||||||
|
if (Objects.isNull(row)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (int j = 0; j < physicalNumberOfCells; j++) {
|
||||||
|
//获取单元格对象
|
||||||
|
Cell cell = row.getCell(j);
|
||||||
|
//获取单元格样式对象
|
||||||
|
CellStyle cellStyle = workbook.createCellStyle();
|
||||||
|
//获取单元格内容对象
|
||||||
|
Font font = workbook.createFont();
|
||||||
|
font.setFontHeightInPoints((short) 12);
|
||||||
|
//一定要装入 样式中才会生效
|
||||||
|
cellStyle.setFont(font);
|
||||||
|
//设置居中对齐
|
||||||
|
cellStyle.setAlignment(HorizontalAlignment.CENTER);
|
||||||
|
cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
|
||||||
|
//设置单元格字体颜色
|
||||||
|
cell.setCellStyle(cellStyle);
|
||||||
|
//获取当前值
|
||||||
|
String stringCellValue = cell.getStringCellValue();
|
||||||
|
if (stringCellValue.contains("*")) {
|
||||||
|
// 创建一个富文本
|
||||||
|
XSSFRichTextString xssfRichTextString = new XSSFRichTextString(stringCellValue);
|
||||||
|
int startIndex = stringCellValue.indexOf("*");
|
||||||
|
int entIndex = stringCellValue.lastIndexOf("*");
|
||||||
|
if (entIndex != 0) {
|
||||||
|
Font font3 = workbook.createFont();
|
||||||
|
font3.setFontHeightInPoints((short) 12);
|
||||||
|
font3.setColor(Font.COLOR_NORMAL);
|
||||||
|
xssfRichTextString.applyFont(0, entIndex, font3);
|
||||||
|
}
|
||||||
|
//设置带*样式
|
||||||
|
Font font1 = workbook.createFont();
|
||||||
|
font1.setFontHeightInPoints((short) 12);
|
||||||
|
font1.setColor(Font.COLOR_RED);
|
||||||
|
xssfRichTextString.applyFont(startIndex, entIndex + 1, font1);
|
||||||
|
//其他样式
|
||||||
|
Font font2 = workbook.createFont();
|
||||||
|
font2.setFontHeightInPoints((short) 12);
|
||||||
|
font2.setColor(Font.COLOR_NORMAL);
|
||||||
|
xssfRichTextString.applyFont(entIndex + 1, stringCellValue.length(), font2);
|
||||||
|
cell.setCellValue(xssfRichTextString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
workbook.write(outputStream);
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error(">>> 导出数据异常:{}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description:
|
||||||
|
* @param workbook
|
||||||
|
* @param firstCol
|
||||||
|
* @Author: wr
|
||||||
|
* @Date: 2024/8/20 10:44
|
||||||
|
*/
|
||||||
|
public static void selectListText(Workbook workbook, int firstCol,CellStyle cellStyle) {
|
||||||
|
Sheet sheet = workbook.getSheetAt(0);
|
||||||
|
for (int i = 2; i < 65535; i++) {
|
||||||
|
Row row = sheet.getRow(i);
|
||||||
|
if(ObjectUtil.isNull(row)){
|
||||||
|
row = sheet.createRow(i);
|
||||||
|
}
|
||||||
|
Cell cell = row.createCell(firstCol);
|
||||||
|
cell.setCellStyle(cellStyle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置隐藏表单来进行下拉框
|
||||||
|
*
|
||||||
|
* @param workbook
|
||||||
|
* @param pullDowns
|
||||||
|
*/
|
||||||
|
private static void setTopLevel(Workbook workbook, List<PullDown> pullDowns) {
|
||||||
|
int num = 0;
|
||||||
|
for (PullDown pullDown : pullDowns) {
|
||||||
|
if (!pullDown.getIsText()) {
|
||||||
|
int sum = pullDown.getStrings().stream().mapToInt(String::length).sum();
|
||||||
|
if (sum == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (sum > 255) {
|
||||||
|
// 创建隐藏sheet
|
||||||
|
String hiddenSheetName = "hiddenSheetA";
|
||||||
|
if (num == 0) {
|
||||||
|
workbook.createSheet(hiddenSheetName);
|
||||||
|
}
|
||||||
|
//false展示隐藏sheet ,true不展示隐藏sheet
|
||||||
|
workbook.setSheetHidden(workbook.getSheetIndex(workbook.getSheet(hiddenSheetName)), true);
|
||||||
|
Sheet sheet = workbook.getSheet(hiddenSheetName);
|
||||||
|
if (num == 0) {
|
||||||
|
//sheet.getLastRowNum无法区分 有一行和没有 所以这里先建一行
|
||||||
|
sheet.createRow(0);
|
||||||
|
}
|
||||||
|
Row row; //创建数据行
|
||||||
|
sheet.setColumnWidth(num, 4000); //设置每列的列宽
|
||||||
|
for (int j = 0; j < pullDown.getStrings().size(); j++) {
|
||||||
|
if (sheet.getLastRowNum() < j) {
|
||||||
|
row = sheet.createRow(j); //创建数据行
|
||||||
|
} else {
|
||||||
|
row = sheet.getRow(j);
|
||||||
|
}
|
||||||
|
//设置对应单元格的值
|
||||||
|
row.createCell(num).setCellValue(pullDown.getStrings().get(j));
|
||||||
|
}
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取根据数值获取列字母(1=A,2=B,3=C,.......,27=AA)
|
||||||
|
*
|
||||||
|
* @param n
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String numberToExcelColumn(int n) {
|
||||||
|
CellReference cellRef = new CellReference(0, n - 1, false, false); // Row and column are 0-based
|
||||||
|
int colIndex = cellRef.getCol();
|
||||||
|
StringBuilder columnName = new StringBuilder();
|
||||||
|
while (colIndex >= 0) {
|
||||||
|
columnName.insert(0, (char) ('A' + (colIndex % 26)));
|
||||||
|
colIndex /= 26;
|
||||||
|
colIndex--;
|
||||||
|
}
|
||||||
|
return columnName.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param workbook
|
||||||
|
* @param firstCol
|
||||||
|
* @param lastCol
|
||||||
|
* @param colName 列A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z
|
||||||
|
* @Description: 当下拉框超过最大字符255,设置隐藏表单来进行展示
|
||||||
|
* @Author: wr
|
||||||
|
* @Date: 2024/8/13 15:07
|
||||||
|
*/
|
||||||
|
public static void selectListMaxLength(Workbook workbook, int firstCol, int lastCol, int row, String colName) {
|
||||||
|
Sheet sheet = workbook.getSheetAt(0);
|
||||||
|
// 生成下拉列表
|
||||||
|
// 设置数据有效性加载在哪个单元格上,四个参数分别是:起始行、终止行、起始列、终止列
|
||||||
|
CellRangeAddressList regions = new CellRangeAddressList(2, 65535, firstCol, lastCol);
|
||||||
|
String strFormula = workbook.getSheetName(1) + "!$" + colName + "$1:$" + colName + "$" + row;
|
||||||
|
XSSFDataValidationConstraint hiddentConstraint = new XSSFDataValidationConstraint(DataValidationConstraint.ValidationType.LIST, strFormula);
|
||||||
|
// 数据有效性对象
|
||||||
|
DataValidationHelper help = new XSSFDataValidationHelper((XSSFSheet) sheet);
|
||||||
|
DataValidation validation = help.createValidation(hiddentConstraint, regions);
|
||||||
|
sheet.addValidationData(validation);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* firstRow 開始行號 根据此项目,默认为2(下标0开始)
|
||||||
|
* lastRow 根据此项目,默认为最大65535
|
||||||
|
*
|
||||||
|
* @param firstCol 区域中第一个单元格的列号 (下标0开始)
|
||||||
|
* @param lastCol 区域中最后一个单元格的列号
|
||||||
|
* @param strings 下拉内容
|
||||||
|
*/
|
||||||
|
public static void selectList(Workbook workbook, int firstCol, int lastCol, String[] strings) {
|
||||||
|
Sheet sheet = workbook.getSheetAt(0);
|
||||||
|
// 生成下拉列表
|
||||||
|
// 只对(x,x)单元格有效
|
||||||
|
CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(1, 65535, firstCol, lastCol);
|
||||||
|
// 生成下拉框内容
|
||||||
|
DataValidationHelper dvHelper = sheet.getDataValidationHelper();
|
||||||
|
XSSFDataValidationConstraint dvConstraint = (XSSFDataValidationConstraint)
|
||||||
|
dvHelper.createExplicitListConstraint(strings);
|
||||||
|
XSSFDataValidation validation = (XSSFDataValidation) dvHelper.createValidation(
|
||||||
|
dvConstraint, cellRangeAddressList);
|
||||||
|
// 对sheet页生效
|
||||||
|
sheet.addValidationData(validation);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取workbook对象
|
* 获取workbook对象
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -0,0 +1,171 @@
|
|||||||
|
package com.njcn.web.utils;
|
||||||
|
|
||||||
|
import cn.hutool.core.text.StrPool;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hongawen
|
||||||
|
* @version 1.0.0
|
||||||
|
* @date 2023年04月19日 16:02
|
||||||
|
*/
|
||||||
|
public class FileUtil {
|
||||||
|
|
||||||
|
/***
|
||||||
|
* 随机生成文件名
|
||||||
|
* @author hongawen
|
||||||
|
* @date 2023/4/19 16:02
|
||||||
|
* @param originalFileName 原文件名
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public static String generateFileName(String originalFileName) {
|
||||||
|
String suffix;
|
||||||
|
if (originalFileName.contains(StrPool.DOT)) {
|
||||||
|
suffix = originalFileName.substring(originalFileName.lastIndexOf(StrPool.DOT));
|
||||||
|
} else {
|
||||||
|
suffix = StrPool.DOT + originalFileName;
|
||||||
|
}
|
||||||
|
return UUID.randomUUID().toString().replace("-", "").toUpperCase() + suffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MultipartFile 转 String
|
||||||
|
*
|
||||||
|
* @param multipartFile 原字符串
|
||||||
|
* @return 成功标记
|
||||||
|
*/
|
||||||
|
public static String multipartFileToString(MultipartFile multipartFile) {
|
||||||
|
StringBuilder txtResult = new StringBuilder();
|
||||||
|
try (
|
||||||
|
InputStreamReader isr = new InputStreamReader(multipartFile.getInputStream(), StandardCharsets.UTF_8);
|
||||||
|
BufferedReader br = new BufferedReader(isr)
|
||||||
|
) {
|
||||||
|
String lineTxt;
|
||||||
|
while ((lineTxt = br.readLine()) != null) {
|
||||||
|
txtResult.append(lineTxt);
|
||||||
|
}
|
||||||
|
return txtResult.toString();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断文件是否为word格式
|
||||||
|
*
|
||||||
|
* @param fileName 文件名
|
||||||
|
*/
|
||||||
|
public static boolean judgeFileIsWord(String fileName) {
|
||||||
|
// 检查文件名是否为空
|
||||||
|
if (StrUtil.isBlank(fileName)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 获取文件扩展名
|
||||||
|
String fileExtension = getFileExtension(fileName);
|
||||||
|
// 定义支持的文件类型
|
||||||
|
String[] allowedExtensions = {"doc", "docx"};
|
||||||
|
|
||||||
|
// 检查扩展名是否在允许的列表中
|
||||||
|
for (String ext : allowedExtensions) {
|
||||||
|
if (ext.equalsIgnoreCase(fileExtension)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断文件是否为pdf格式
|
||||||
|
*
|
||||||
|
* @param fileName 文件名
|
||||||
|
*/
|
||||||
|
public static boolean judgeFileIsPdf(String fileName) {
|
||||||
|
// 检查文件名是否为空
|
||||||
|
if (StrUtil.isBlank(fileName)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 获取文件扩展名
|
||||||
|
String fileExtension = getFileExtension(fileName);
|
||||||
|
// 定义支持的文件类型
|
||||||
|
String[] allowedExtensions = {"pdf"};
|
||||||
|
|
||||||
|
// 检查扩展名是否在允许的列表中
|
||||||
|
for (String ext : allowedExtensions) {
|
||||||
|
if (ext.equalsIgnoreCase(fileExtension)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断文件是否为excel格式
|
||||||
|
*
|
||||||
|
* @param fileName 文件名
|
||||||
|
*/
|
||||||
|
public static boolean judgeFileIsExcel(String fileName) {
|
||||||
|
// 检查文件名是否为空
|
||||||
|
if (StrUtil.isBlank(fileName)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 获取文件扩展名
|
||||||
|
String fileExtension = getFileExtension(fileName);
|
||||||
|
// 定义支持的文件类型
|
||||||
|
String[] allowedExtensions = {"xls", "xlsx"};
|
||||||
|
|
||||||
|
// 检查扩展名是否在允许的列表中
|
||||||
|
for (String ext : allowedExtensions) {
|
||||||
|
if (ext.equalsIgnoreCase(fileExtension)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断文件是否为excel格式
|
||||||
|
*
|
||||||
|
* @param fileName 文件名
|
||||||
|
*/
|
||||||
|
public static boolean judgeFileIsZip(String fileName) {
|
||||||
|
// 检查文件名是否为空
|
||||||
|
if (StrUtil.isBlank(fileName)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 获取文件扩展名
|
||||||
|
String fileExtension = getFileExtension(fileName);
|
||||||
|
// 定义支持的文件类型
|
||||||
|
String[] allowedExtensions = {"zip", "rar"};
|
||||||
|
|
||||||
|
// 检查扩展名是否在允许的列表中
|
||||||
|
for (String ext : allowedExtensions) {
|
||||||
|
if (ext.equalsIgnoreCase(fileExtension)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从文件名中提取扩展名
|
||||||
|
*
|
||||||
|
* @param fileName 文件名
|
||||||
|
* @return 扩展名
|
||||||
|
*/
|
||||||
|
private static String getFileExtension(String fileName) {
|
||||||
|
int dotIndex = fileName.lastIndexOf('.');
|
||||||
|
if (dotIndex == -1) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return fileName.substring(dotIndex + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user