初始代码

This commit is contained in:
wangmingwei
2026-04-21 17:41:09 +08:00
parent 186ec6683a
commit b686ecac5f
493 changed files with 52349 additions and 0 deletions

View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>yunzhupaas-boot-common</artifactId>
<groupId>com.yunzhupaas</groupId>
<version>5.2.0-RELEASE</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>yunzhupaas-common-office</artifactId>
<dependencies>
<dependency>
<groupId>com.yunzhupaas</groupId>
<artifactId>yunzhupaas-common-core</artifactId>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-base</artifactId>
<exclusions>
<exclusion>
<artifactId>validation-api</artifactId>
<groupId>javax.validation</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.github.librepdf</groupId>
<artifactId>openpdf</artifactId>
</dependency>
<dependency>
<groupId>com.github.librepdf</groupId>
<artifactId>openpdf-fonts-extra</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,118 @@
package com.yunzhupaas.excel;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.afterturn.easypoi.excel.entity.params.ExcelForEachParams;
import cn.afterturn.easypoi.excel.export.styler.IExcelExportStyler;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.DefaultIndexedColorMap;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFColor;
public class ExcelExportStyler implements IExcelExportStyler {
private static final short FONT_SIZE_TWELVE = 12;
private Workbook workbook;
private CellStyle headStyle;
private XSSFCellStyle cellStyle;
public ExcelExportStyler(Workbook workbook) {
this.workbook = workbook;
this.headStyle = getBaseCellStyle();
this.cellStyle = (XSSFCellStyle) workbook.createCellStyle();
}
@Override
public CellStyle getHeaderStyle(short color) {
CellStyle style = this.headStyle;
return style;
}
@Override
public CellStyle getTitleStyle(short color) {
XSSFCellStyle style = (XSSFCellStyle) this.headStyle;
style.setFont(getFont(workbook, FONT_SIZE_TWELVE, true));
// 自定义背景颜色
byte[] rgb = new byte[]{(byte) 221, (byte) 220, (byte) 223}; // RGB值
XSSFColor customColor = new XSSFColor(rgb, new DefaultIndexedColorMap());
style.setFillForegroundColor(customColor);
//设置填充模式为实心填充
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
return style;
}
public void setBlackBorder(CellStyle style) {
// 设置边框样式为细线
style.setBorderBottom(BorderStyle.THIN);
style.setBorderLeft(BorderStyle.THIN);
style.setBorderTop(BorderStyle.THIN);
style.setBorderRight(BorderStyle.THIN);
// 设置单元格颜色
style.setBottomBorderColor(IndexedColors.BLACK.getIndex());
style.setLeftBorderColor(IndexedColors.BLACK.getIndex());
style.setRightBorderColor(IndexedColors.BLACK.getIndex());
style.setTopBorderColor(IndexedColors.BLACK.getIndex());
// 单元格内容水平居中
style.setAlignment(HorizontalAlignment.LEFT);
// 单元格内容垂直居中
style.setVerticalAlignment(VerticalAlignment.CENTER);
// 单元格内的文本超出单元格宽度时自动换行
style.setWrapText(true);
}
@Override
public CellStyle getStyles(boolean parity, ExcelExportEntity entity) {
XSSFCellStyle style = cellStyle;
this.setBlackBorder(style);
// 单元格内容水平居中
style.setAlignment(HorizontalAlignment.LEFT);
// 单元格内容垂直居中
style.setVerticalAlignment(VerticalAlignment.CENTER);
// 单元格内的文本超出单元格宽度时自动换行
style.setWrapText(true);
return style;
}
@Override
public CellStyle getStyles(Cell cell, int dataRow, ExcelExportEntity entity, Object obj, Object data) {
return getStyles(true, entity);
}
@Override
public CellStyle getTemplateStyles(boolean isSingle, ExcelForEachParams excelForEachParams) {
return null;
}
/**
* 表头单元格样式
*
* @return
*/
private CellStyle getBaseCellStyle() {
CellStyle style = workbook.createCellStyle();
this.setBlackBorder(style);
// 单元格内容水平居中
style.setAlignment(HorizontalAlignment.CENTER);
return style;
}
/**
* 字体修改
*
* @param size 字号
* @param isBold 加粗
* @return
*/
private Font getFont(Workbook workbook, short size, boolean isBold) {
Font font = workbook.createFont();
font.setFontName("宋体");
font.setBold(isBold);
font.setFontHeightInPoints(size);
return font;
}
}

View File

@@ -0,0 +1,10 @@
package com.yunzhupaas.excel;
import java.util.Map;
@FunctionalInterface
public interface ExcelFunction {
void apply(ExcelHelper compute, Map<String, Object> params);
}

View File

@@ -0,0 +1,158 @@
package com.yunzhupaas.excel;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import com.yunzhupaas.excel.handle.ExcelCommentHandle;
import com.yunzhupaas.excel.handle.ExcelDataValidation;
import com.yunzhupaas.excel.handle.ExcelRequireRedColor;
import com.yunzhupaas.model.ExcelColumnAttr;
import com.yunzhupaas.model.ExcelModel;
import com.yunzhupaas.util.ExcelUtil;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFCell;
import java.util.*;
import java.util.stream.Collectors;
@Data
@NoArgsConstructor
public class ExcelHelper {
// 是否生成示例数据
public boolean needExampleData = false;
boolean initPre = false;
boolean initPost = false;
/**
* 控件信息
*/
List<ExcelColumnAttr> models;
/**
* 控件信息和excel导出的key对应关系
*/
Map<String, ExcelColumnAttr> modelMap = new HashMap<>();
/**
* excel参数
*/
ExportParams exportParams;
/**
* 导出字段信息
*/
List<ExcelExportEntity> entities;
private Workbook workbook;
private List<ExcelFunction> preHandleFunctions = new ArrayList<>();
private List<ExcelFunction> postHandleFunctions = new ArrayList<>();
private Map<String, String[]> optionMap;
/**
* 额外参数
*/
private Map<String, Object> extraParams = new HashMap<>();
/**
* 存在子表
*/
private boolean complexTable;
private void preDataHandle() {
for (ExcelExportEntity entity : this.entities) {
if (CollectionUtils.isNotEmpty(entity.getList())) {
this.complexTable = true;
break;
}
}
// 控件映射
for (ExcelColumnAttr model : this.models) {
String key = model.getKey();
modelMap.put(key, model);
}
}
public void init(Workbook workbook, ExportParams exportParams, List<ExcelExportEntity> entities, ExcelModel excelModel) {
this.workbook = workbook;
this.exportParams = exportParams != null ? exportParams : new ExportParams();
this.models = excelModel.getModels() != null ? excelModel.getModels() : new ArrayList<>();
this.entities = entities != null ? entities : new ArrayList<>();
this.optionMap = excelModel.getOptionMap() != null ? excelModel.getOptionMap() : new HashMap<>();
this.preDataHandle();
}
private void initPreHandle() {
addPreHandle(new ExcelCommentHandle()::execute);
this.initPre = true;
}
private void initPostHandle() {
addPostHandle(new ExcelDataValidation()::execute);
addPostHandle(new ExcelRequireRedColor()::execute);
this.initPost = true;
}
public void doPreHandle() {
if (!initPre) {
this.initPreHandle();
}
addPreHandle(new ExcelCommentHandle()::execute);
preHandleFunctions.stream().filter(Objects::nonNull).collect(Collectors.toList()).forEach(item -> item.apply(this, this.extraParams));
}
public void doPostHandle() {
if (!initPost) {
this.initPostHandle();
}
postHandleFunctions.stream().filter(Objects::nonNull).collect(Collectors.toList()).forEach(item -> item.apply(this, this.extraParams));
// 移除标题的括号文字
this.removeTitleConclusion();
// 添加border线
this.addCellBorder();
}
private void addCellBorder() {
Sheet sheet = workbook.getSheet(exportParams.getSheetName());
int rowLen = sheet.getLastRowNum();
int startRowLen = complexTable ? 2 : 1;
int lastCellNum = sheet.getRow(startRowLen - 1).getLastCellNum();
CellStyle style = workbook.createCellStyle();
ExcelExportStyler excelExportStyler = new ExcelExportStyler(workbook);
for (int i = startRowLen; i <= rowLen; i++) {
Row row = sheet.getRow(i);
for (int j = 0; j < lastCellNum; j++) {
Cell cell = row.getCell(j);
if (cell == null) cell = row.createCell(j);
excelExportStyler.setBlackBorder(style);
//设置单元格为文本格式
DataFormat dataFormat = workbook.createDataFormat();
style.setDataFormat(dataFormat.getFormat("@"));
cell.setCellStyle(style);
}
}
}
private void removeTitleConclusion() {
Sheet sheet = workbook.getSheet(exportParams.getSheetName());
int rowLen = complexTable ? 2 : 1;
for (int i = 0; i < rowLen; i++) {
Row headerRow = sheet.getRow(i);
int lastCellNum = headerRow.getLastCellNum();
for (int j = 0; j < lastCellNum; j++) {
Cell cell = headerRow.getCell(j);
if (cell == null) continue;
String name = ((XSSFCell) cell).getRichStringCellValue().getString();
if (ExcelUtil.matcherFind(name)) {
((XSSFCell) cell).getRichStringCellValue().setString(name.substring(0, name.lastIndexOf("(")));
}
}
}
}
public void addPreHandle(ExcelFunction... functions) {
Collections.addAll(preHandleFunctions, functions);
}
public void addPostHandle(ExcelFunction... functions) {
Collections.addAll(postHandleFunctions, functions);
}
}

View File

@@ -0,0 +1,8 @@
package com.yunzhupaas.excel;
import java.util.Map;
public interface ExcelPostHandle {
void execute(ExcelHelper data, Map<String, Object> params);
}

View File

@@ -0,0 +1,8 @@
package com.yunzhupaas.excel;
import java.util.Map;
public interface ExcelPreHandle {
void execute(ExcelHelper data, Map<String, Object> params);
}

View File

@@ -0,0 +1,86 @@
package com.yunzhupaas.excel.handle;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import com.yunzhupaas.excel.ExcelHelper;
import com.yunzhupaas.excel.ExcelPreHandle;
import com.yunzhupaas.util.ExcelUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFCell;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
* excel添加批注
*/
public class ExcelCommentHandle implements ExcelPreHandle {
String sheetName;
Workbook workbook;
int headerRowLen;
int lastRowNum;
/**
* workbook增加标题批注
*
* @param workbook 工作簿
* @param sheetName 工作表名称
* @param columnIndex 列索引,从0开始
* @param comment 批注内容
*/
public void addComment(Workbook workbook, String sheetName, int rowIndex, int columnIndex, String comment) {
Sheet sheet = workbook.getSheet(sheetName);
Row headerRow = sheet.getRow(rowIndex);
Cell headerCell = headerRow.getCell(columnIndex);
// 判断是否存在批注
Comment cellComment = headerCell.getCellComment();
if (!Objects.isNull(cellComment)) {
headerCell.setCellComment(null);
}
Drawing<?> drawing = sheet.createDrawingPatriarch();
CreationHelper factory = workbook.getCreationHelper();
ClientAnchor anchor = factory.createClientAnchor();
anchor.setRow1(rowIndex);
anchor.setCol1(columnIndex);
Comment headerComment = drawing.createCellComment(anchor);
RichTextString str = factory.createRichTextString(comment);
headerComment.setString(str);
headerCell.setCellComment(headerComment);
}
@Override
public void execute(ExcelHelper data, Map<String, Object> params) {
List<ExcelExportEntity> list = data.getEntities();
ExportParams exportParams = data.getExportParams();
workbook = data.getWorkbook();
params.put("sheetName", sheetName);
this.sheetName = exportParams.getSheetName();
Sheet sheet = workbook.getSheet(exportParams.getSheetName());
headerRowLen = data.isComplexTable() ? 2 : 1;
sheet.createFreezePane(exportParams.getFreezeCol(),headerRowLen);
lastRowNum = sheet.getLastRowNum();
for (int i = 0; i < headerRowLen; i++) {
Row headerRow = sheet.getRow(i);
int lastCellNum = headerRow.getLastCellNum();
for (int j = 0; j < lastCellNum; j++) {
Cell cell = headerRow.getCell(j);
this.addComment(cell, i, j);
}
}
}
private void addComment(Cell cell, int rowIndex, int columnIndex) {
if (cell == null) return;
String name = ((XSSFCell) cell).getRichStringCellValue().getString();
if (StringUtils.isBlank(name)) return;
String id = ExcelUtil.getIdFromCellValue(name);
if (StringUtils.isNotBlank(id)) {
this.addComment(workbook, sheetName, rowIndex, columnIndex, id);
}
}
}

View File

@@ -0,0 +1,122 @@
package com.yunzhupaas.excel.handle;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import com.yunzhupaas.excel.ExcelHelper;
import com.yunzhupaas.excel.ExcelPostHandle;
import com.yunzhupaas.model.ExcelColumnAttr;
import com.yunzhupaas.util.ExcelUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.xssf.usermodel.XSSFCell;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
* excel添加数据下拉校验
* 下拉选择单选、单选框组、开关导入EXCEL内生成【数据验证】下拉框
*/
public class ExcelDataValidation implements ExcelPostHandle {
String sheetName;
Map<String, ExcelColumnAttr> modelMap;
ExcelHelper data;
private Workbook workbook;
int hiddenIndex = 0;
int headerRowLen = 0;
int lastRowNum = 0;
Map<String, String[]> optionMap;
/**
* 用于下拉内容很多字符超过255
* <p>
* 下拉选项先将数据放到另一个sheet页然后下拉的数据再去sheet页读取解决普通下拉数据量太多下拉不显示问题
* <p>
* firstRow 开始行号(下标0开始)
* <p>
* lastRow 结束行号最大65535
* <p>
* firstCol 区域中第一个单元格的列号 (下标0开始)
* <p>
* lastCol 区域中最后一个单元格的列号
* <p>
* sheetIndex 创建的sheet的index。如果有多个下拉想放到sheet页则需要设置不同的sheetIndex注意不能设置为00为主数据页
* <p>
* selectList 下拉内容
*/
public void selectLargeList(Workbook workbook, int firstRow, int lastRow, int firstCol, int lastCol, int sheetIndex, String[] selectList) {
Sheet sheet = workbook.getSheetAt(0);
//将下拉框数据放到新的sheet里然后excle通过新的sheet数据加载下拉框数据
String sheetName = "sheetName" + sheetIndex;
Sheet hidden = workbook.createSheet(sheetName);
//创建单元格对象
Cell cell = null;
//遍历我们上面的数组将数据取出来放到新sheet的单元格中
for (int i = 0, length = selectList.length; i < length; i++) {
//取出数组中的每个元素
String name = selectList[i];
//根据i创建相应的行对象说明我们将会把每个元素单独放一行
Row row = hidden.createRow(i);
//创建每一行中的第一个单元格
cell = row.createCell(0);
//然后将数组中的元素赋值给这个单元格
cell.setCellValue(name);
}
// 创建名称,可被其他单元格引用
String refers = sheetName + "!$A$1:$A$" + selectList.length;
//这个3代表我的下拉数据从第三行开始生效前面1,2行不显示下拉你们根据自己情况修改。
CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(firstRow, lastRow, firstCol, lastCol);
DataValidationHelper helper = sheet.getDataValidationHelper();
DataValidationConstraint constraint = helper.createFormulaListConstraint(refers);
DataValidation dataValidation = helper.createValidation(constraint, cellRangeAddressList);
//将第sheetIndex个sheet设置为隐藏
sheet.addValidationData(dataValidation);
hiddenIndex++;
}
@Override
public void execute(ExcelHelper data, Map<String, Object> params) {
hiddenIndex = 0;
workbook = data.getWorkbook();
optionMap = data.getOptionMap() != null ? data.getOptionMap() : new HashMap<>();
List<ExcelExportEntity> list = data.getEntities();
ExportParams exportParams = data.getExportParams();
this.sheetName = exportParams.getSheetName();
this.data = data;
modelMap = data.getModelMap() != null ? data.getModelMap() : new HashMap<>();
Sheet sheet = workbook.getSheet(exportParams.getSheetName());
headerRowLen = data.isComplexTable() ? 2 : 1;
lastRowNum = sheet.getLastRowNum();
for (int i = 0; i < headerRowLen; i++) {
Row headerRow = sheet.getRow(i);
int lastCellNum = headerRow.getLastCellNum();
for (int j = 0; j < lastCellNum; j++) {
Cell cell = headerRow.getCell(j);
addDataValidation(cell, j);
}
}
// 隐藏校验sheet
for (int i = 1; i <= hiddenIndex; i++) {
workbook.setSheetHidden(i, true);
}
}
private void addDataValidation(Cell cell, int columnIndex) {
if (cell == null) return;
String key = ((XSSFCell) cell).getRichStringCellValue().getString();
if (StringUtils.isBlank(key)) return;
String id = ExcelUtil.getIdFromCellValue(key);
ExcelColumnAttr model = modelMap.get(id);
if (Objects.isNull(model)) return;
String[] options = optionMap.get(id);
if (options != null && options.length > 0) {
selectLargeList(workbook, headerRowLen, lastRowNum, columnIndex, columnIndex, columnIndex, options);
}
}
}

View File

@@ -0,0 +1,61 @@
package com.yunzhupaas.excel.handle;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.yunzhupaas.excel.ExcelHelper;
import com.yunzhupaas.excel.ExcelPostHandle;
import com.yunzhupaas.model.ExcelColumnAttr;
import com.yunzhupaas.util.ExcelUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFCell;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
* excel必填字段的字体颜色修改为红色
*/
public class ExcelRequireRedColor implements ExcelPostHandle {
Map<String, ExcelColumnAttr> modelMap;
Workbook workbook;
@Override
public void execute(ExcelHelper data, Map<String, Object> params) {
ExportParams exportParams = data.getExportParams();
workbook = data.getWorkbook();
modelMap = data.getModelMap() != null ? data.getModelMap() : new HashMap<>();
Sheet sheet = workbook.getSheet(exportParams.getSheetName());
int rowLen = data.isComplexTable() ? 2 : 1;
for (int i = 0; i < rowLen; i++) {
Row headerRow = sheet.getRow(i);
int lastCellNum = headerRow.getLastCellNum();
for (int j = 0; j < lastCellNum; j++) {
Cell cell = headerRow.getCell(j);
judgeRequired(cell);
}
}
}
private void judgeRequired(Cell cell) {
if (cell == null) return;
String key = ((XSSFCell) cell).getRichStringCellValue().getString();
if (StringUtils.isNotBlank(key)) {
String id = ExcelUtil.getIdFromCellValue(key);
ExcelColumnAttr model = modelMap.get(id);
if (Objects.isNull(model)) return;
if (model.isRequire()) {
((XSSFCell) cell).getRichStringCellValue().setString("*" + key);
CellStyle originalCellStyle = cell.getCellStyle();
Font font = workbook.createFont();
font.setColor(model.getFontColor());
font.setBold(true);
CellStyle redCellStyle = workbook.createCellStyle();
redCellStyle.cloneStyleFrom(originalCellStyle); // 复制原有样式避免覆盖其他设置
redCellStyle.setFont(font);
cell.setCellStyle(redCellStyle);
}
}
}
}

View File

@@ -0,0 +1,34 @@
package com.yunzhupaas.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.poi.ss.usermodel.IndexedColors;
/**
* 表头属性
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ExcelColumnAttr {
/**
* key
*/
private String key;
/**
* 字段名称
*/
private String name;
/**
* 是否必填
*/
private boolean require;
/**
* 标题字体颜色
*/
private short fontColor;
}

View File

@@ -0,0 +1,37 @@
package com.yunzhupaas.model;
import lombok.Data;
import java.util.List;
import java.util.Map;
/**
* 导入数据表单
*
* @author 云筑产品开发平台组
* @version v5.0.0
* @copyright 深圳市乐程软件有限公司
* @date 2024/5/18 11:45:52
*/
@Data
public class ExcelImportForm {
/**
* 数据数组
*/
private List<Map<String, Object>> list;
/**
* 菜单ID
*/
private String menuId;
/**
* 跳过数据预览
*/
private boolean type;
/**
* 文件名称
*/
private String fileName;
}

View File

@@ -0,0 +1,41 @@
package com.yunzhupaas.model;
import lombok.Data;
import java.util.List;
import java.util.Map;
/**
* 导入结果展示对象
*
* @author 云筑产品开发平台组
* @version v5.0.0
* @copyright 深圳市乐程软件有限公司
* @date 2024/5/18 11:44:31
*/
@Data
public class ExcelImportVO {
/**
* 导入成功条数
*/
private int snum;
/**
* 导入失败条数
*/
private int fnum;
/**
* 导入结果状态(0,成功 1失败)
*/
private int resultType;
/**
* 失败结果
*/
private List<Map<String, Object>> failResult;
/**
* 失败结果
*/
private List<Map<String, Object>> headerRow;
}

View File

@@ -0,0 +1,54 @@
package com.yunzhupaas.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* 表工具通用参数
*
* @author 云筑产品开发平台组
* @version v5.0.0
* @copyright 深圳市乐程软件有限公司
* @date 2024/5/18 11:46:16
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ExcelModel {
/**
* 选中得字段key
*/
List<String> selectKey;
/**
* 控件信息
*/
List<ExcelColumnAttr> models;
/**
* 一条数据
*/
Map<String, Object> dataMap;
/**
* 下拉数据
*/
private Map<String, String[]> optionMap;
/**
* excel抬头
*/
private boolean hasHeader = false;
/**
* excel抬头-内容
*/
private List<String> headerContent = new ArrayList<>();
}

View File

@@ -0,0 +1,45 @@
package com.yunzhupaas.model;
import lombok.Data;
import java.util.List;
/**
* 导入预览表头对象
*
* @author 云筑产品开发平台组
* @version v5.0.0
* @copyright 深圳市乐程软件有限公司
* @date 2024/5/18 11:38:15
*/
@Data
public class ExcelViewFieldModel {
private String id;
private String fullName;
private String yunzhupaasKey;
private List<ExcelViewFieldModel> children;
public ExcelViewFieldModel(String id, String fullName, List<ExcelViewFieldModel> children) {
this.id = id;
this.fullName = fullName;
this.children = children;
}
public ExcelViewFieldModel(String id, String fullName) {
this.id = id;
this.fullName = fullName;
}
public ExcelViewFieldModel(String id, String fullName, String yunzhupaasKey, List<ExcelViewFieldModel> children) {
this.id = id;
this.fullName = fullName;
this.yunzhupaasKey = yunzhupaasKey;
this.children = children;
}
public ExcelViewFieldModel(String id, String fullName, String yunzhupaasKey) {
this.id = id;
this.fullName = fullName;
this.yunzhupaasKey = yunzhupaasKey;
}
}

View File

@@ -0,0 +1,308 @@
package com.yunzhupaas.util;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import jakarta.servlet.http.HttpServletResponse;
import com.yunzhupaas.exception.ImportException;
import com.yunzhupaas.support.MyStandardMultipartFile;
import lombok.Cleanup;
import org.apache.catalina.core.ApplicationPart;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.tomcat.util.http.fileupload.FileItem;
import org.apache.tomcat.util.http.fileupload.FileItemFactory;
import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.net.URLEncoder;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司
* @date 2024/3/16 10:51
*/
public class ExcelUtil {
/**
* Workbook 转 MultipartFile
*
* @param workbook excel文档
* @param fileName 文件名
* @return
*/
public static MultipartFile workbookToCommonsMultipartFile(Workbook workbook, String fileName) {
//Workbook转FileItem
FileItemFactory factory = new DiskFileItemFactory(16, null);
FileItem fileItem = factory.createItem("textField", "text/plain", true, fileName);
try {
OutputStream os = fileItem.getOutputStream();
workbook.write(os);
os.close();
//FileItem转MultipartFile
MultipartFile multipartFile = new MyStandardMultipartFile(new ApplicationPart(fileItem, null), fileName);
return multipartFile;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 下载excel
*
* @param fileName excel名称
* @param workbook
*/
public static void dowloadExcel(Workbook workbook, String fileName) {
try {
HttpServletResponse response = ServletUtil.getResponse();
response.setCharacterEncoding("UTF-8");
response.setHeader("content-Type", "application/vnd.ms-excel");
response.setHeader("Content-Disposition",
"attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
workbook.write(response.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* excel转成实体
*
* @param filePath 路径
* @param titleRows 行
* @param headerRows 列
* @param pojoClass 实体
* @param <T>
* @return
*/
public static <T> List<T> importExcel(String filePath, Integer titleRows, Integer headerRows, Class<T> pojoClass) {
if (StringUtils.isBlank(filePath)) {
return null;
}
ImportParams params = new ImportParams();
params.setTitleRows(titleRows);
params.setHeadRows(headerRows);
List<T> list = null;
try {
list = ExcelImportUtil.importExcel(new File(com.yunzhupaas.util.XSSEscape.escapePath(filePath)), pojoClass, params);
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
/**
* excel转成实体
*
* @param file 文件
* @param titleRows 行
* @param headerRows 列
* @param pojoClass 实体
* @param <T>
* @return
*/
public static <T> List<T> importExcel(File file, Integer titleRows, Integer headerRows, Class<T> pojoClass) throws ImportException {
if (file == null) {
return null;
}
ImportParams params = new ImportParams();
params.setTitleRows(titleRows);
params.setHeadRows(headerRows);
List<T> list = null;
try {
list = ExcelImportUtil.importExcel(file, pojoClass, params);
} catch (Exception e) {
throw new ImportException(e.getMessage());
}
return list;
}
/**
* excel转成实体
*
* @param inputStream 文件流
* @param titleRows 行
* @param headerRows 列
* @param pojoClass 实体
* @param <T>
* @return
*/
public static <T> List<T> importExcelByInputStream(InputStream inputStream, Integer titleRows, Integer headerRows, Class<T> pojoClass) throws Exception {
if (inputStream == null) {
return null;
}
ImportParams params = new ImportParams();
params.setTitleRows(titleRows);
params.setHeadRows(headerRows);
List<T> list = null;
list = ExcelImportUtil.importExcel(inputStream, pojoClass, params);
return list;
}
/**
* excel转成实体
*
* @param file 文件
* @param titleRows 行
* @param headerRows 列
* @param pojoClass 实体
* @param <T>
* @return
*/
public static <T> List<T> importExcel(MultipartFile file, Integer titleRows, Integer headerRows, Class<T> pojoClass) {
ImportParams params = new ImportParams();
params.setTitleRows(titleRows);
params.setHeadRows(headerRows);
List<T> list = null;
try {
list = ExcelImportUtil.importExcel(file.getInputStream(), pojoClass, params);
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
/**
* 备用方案,读取不到时间暂用此方法
* 通过基础poi读取NUMERIC转换成时间格式
*
* @param
* @return
* @copyright 深圳市乐程软件有限公司
* @date 2023/2/3
*/
public static void imoportExcelToMap(File file, Integer titleIndex, List<Map> excelDataList) {
List<Map<String, Object>> mapList = new ArrayList<>();
FileInputStream inputStream = null;
try {
String fileName = file.getName();
@Cleanup Workbook workbook = null;
inputStream = new FileInputStream(file);
try {
workbook = new HSSFWorkbook(inputStream);
} catch (Exception e) {
inputStream = new FileInputStream(file);
workbook = new XSSFWorkbook(inputStream);
}
Sheet sheet = workbook.getSheetAt(0);
Row titleRow = sheet.getRow(titleIndex - 1);
for (int i = titleIndex; i < sheet.getPhysicalNumberOfRows(); i++) {
Row row = sheet.getRow(i);
Map<String, Object> map = new HashMap<>();
for (int j = 0; j < row.getPhysicalNumberOfCells(); j++) {
Cell cell = row.getCell(j);
Cell titleCell = titleRow.getCell(j);
if (cell != null && org.apache.poi.ss.usermodel.DateUtil.isCellDateFormatted(cell)) {
short format = cell.getCellStyle().getDataFormat();
if (cell.getDateCellValue() != null && format > 0) {
//表头数据
String titleName = titleCell.getStringCellValue();
if (StringUtil.isEmpty(titleName)) {
titleName = sheet.getRow(titleIndex - 2).getCell(j).getStringCellValue();
}
//单元格内容
Date dateCellValue = cell.getDateCellValue();
String valueName = DateUtil.daFormat(dateCellValue);
map.put(titleName, valueName);
}
}
}
mapList.add(map);
}
//基础poi读取到时间同步到easypoi读取到的数据中去
if (!CollectionUtils.sizeIsEmpty(mapList)) {
for (int n = 0; n < mapList.size(); n++) {
Map<String, Object> a = mapList.get(n);
Map b = excelDataList.get(n);
if (a != null) {
for (String key : a.keySet()) {
if (b.containsKey(key)) b.put(key, a.get(key));
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static InputStream solveOrginTitle(File file, Integer rowLen) throws IOException {
return solveOrginTitle(file, 0, rowLen);
}
public static InputStream solveOrginTitle(File file, Integer titleIndex, Integer rowLen) throws IOException {
@Cleanup Workbook workbook = WorkbookFactory.create(file);
Sheet sheet = workbook.getSheetAt(0);
for (int i = titleIndex; i < titleIndex + rowLen; i++) {
Row headerRow = sheet.getRow(i);
int lastCellNum = headerRow.getLastCellNum();
for (int j = 0; j < lastCellNum; j++) {
Cell cell = headerRow.getCell(j);
if (cell == null) {
continue;
}
String name = cell.getStringCellValue();
Comment cellComment = cell.getCellComment();
//都没有标题就跳过
if (StringUtils.isEmpty(name) && cellComment == null) {
continue;
}
//有标题没批注,说明表头有问题
if (Objects.isNull(cellComment)) {
throw new RuntimeException();
}
name = name + "(" + cellComment.getString().getString() + ")";
cell.setCellValue(name);
}
}
MultipartFile multipartFile = ExcelUtil.workbookToCommonsMultipartFile(workbook, file.getName());
InputStream inputStream = multipartFile.getInputStream();
return inputStream;
}
/**
* 判断字符串内有没有括号
*
* @param str
* @return
*/
public static boolean matcherFind(String str) {
Pattern pattern = Pattern.compile("(.*)\\((.*?)\\)");
Matcher matcher = pattern.matcher(str);
return matcher.find();
}
/**
* 获取标题括号内得id
*
* @param cellValue
* @return
*/
public static String getIdFromCellValue(String cellValue) {
String id = "";
if (matcherFind(cellValue)) {
id = cellValue.substring(cellValue.lastIndexOf("(") + 1, cellValue.lastIndexOf(")"));
}
return id;
}
}

View File

@@ -0,0 +1,52 @@
package com.yunzhupaas.util;
import com.lowagie.text.pdf.PdfReader;
import lombok.Cleanup;
import lombok.extern.slf4j.Slf4j;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
/**
* PDF工具
* @author 云筑产品开发平台组
* @version V5.2.0
* @copyright 深圳市乐程软件有限公司
* @date 2025/1/14 15:00
*/
@Slf4j
public class PdfUtil {
/**
* 校验pdf文件是否包含js脚本
**/
public static boolean containsJavaScript(File file) {
try {
return containsJavaScript(Files.readAllBytes(file.toPath()));
} catch (IOException e) {
log.error("PDF文档解析失败: {}", e.getMessage());
}
return false;
}
/**
* 校验pdf文件是否包含js脚本
**/
public static boolean containsJavaScript(byte[] filebyte) {
try {
@Cleanup PdfReader reader = new PdfReader(filebyte);
String javaScript = reader.getJavaScript();
if(StringUtil.isNotEmpty(javaScript)) {
return true;
}
} catch (Exception e) {
log.error("PDF文档解析失败: {}", e.getMessage());
}
return false;
}
}

View File

@@ -0,0 +1,161 @@
package com.yunzhupaas.util;
import lombok.Cleanup;
import org.apache.poi.ooxml.POIXMLDocument;
import org.apache.poi.xwpf.usermodel.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
*
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司
* @date 2024/3/16 10:57
*/
public class WordUtil {
/**
* 根据模板生成新word文档
* 判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入
* @param inputUrl 模板存放地址
* @param outputUrl 新文档存放地址
* @param textMap 需要替换的信息集合
* @param tableList 需要插入的表格信息集合
* @return 成功返回true,失败返回false
*/
public static void changWord(String inputUrl, String outputUrl, Map<String, String> textMap, List<String[]> tableList) {
boolean changeFlag = true;
try {
XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(inputUrl));
changeText(document, textMap);
changeTable(document, textMap, tableList);
File file = new File(com.yunzhupaas.util.XSSEscape.escapePath(outputUrl));
@Cleanup FileOutputStream stream = new FileOutputStream(file);
document.write(stream);
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 替换段落文本
* @param document docx解析对象
* @param textMap 需要替换的信息集合
*/
public static void changeText(XWPFDocument document, Map<String, String> textMap){
List<XWPFParagraph> paragraphs = document.getParagraphs();
for (XWPFParagraph paragraph : paragraphs) {
String text = paragraph.getText();
if(checkText(text)){
List<XWPFRun> runs = paragraph.getRuns();
for (XWPFRun run : runs) {
run.setText(changeValue(run.toString(), textMap),0);
}
}
}
}
/**
* 替换表格对象方法
* @param document docx解析对象
* @param textMap 需要替换的信息集合
* @param tableList 需要插入的表格信息集合
*/
public static void changeTable(XWPFDocument document, Map<String, String> textMap, List<String[]> tableList){
List<XWPFTable> tables = document.getTables();
for (int i = 0; i < tables.size(); i++) {
XWPFTable table = tables.get(i);
if(table.getRows().size()>1){
if(checkText(table.getText())){
List<XWPFTableRow> rows = table.getRows();
eachTable(rows, textMap);
}else{
insertTable(table, tableList);
}
}
}
}
/**
* 遍历表格
* @param rows 表格行对象
* @param textMap 需要替换的信息集合
*/
public static void eachTable(List<XWPFTableRow> rows , Map<String, String> textMap){
for (XWPFTableRow row : rows) {
List<XWPFTableCell> cells = row.getTableCells();
for (XWPFTableCell cell : cells) {
if(checkText(cell.getText())){
List<XWPFParagraph> paragraphs = cell.getParagraphs();
for (XWPFParagraph paragraph : paragraphs) {
List<XWPFRun> runs = paragraph.getRuns();
for (XWPFRun run : runs) {
run.setText(changeValue(run.toString(), textMap),0);
}
}
}
}
}
}
/**
* 为表格插入数据,行数不够添加新行
* @param table 需要插入数据的表格
* @param tableList 插入数据集合
*/
public static void insertTable(XWPFTable table, List<String[]> tableList){
for(int i = 1; i < tableList.size(); i++){
XWPFTableRow row =table.createRow();
}
List<XWPFTableRow> rows = table.getRows();
for(int i = 1; i < rows.size(); i++){
XWPFTableRow newRow = table.getRow(i);
List<XWPFTableCell> cells = newRow.getTableCells();
for(int j = 0; j < cells.size(); j++){
XWPFTableCell cell = cells.get(j);
cell.setText(tableList.get(i-1)[j]);
}
}
}
/**
* 判断文本中时候包含$
* @param text 文本
* @return 包含返回true,不包含返回false
*/
public static boolean checkText(String text){
boolean check = false;
if(text.indexOf("$")!= -1){
check = true;
}
return check;
}
/**
* 匹配传入信息集合与模板
* @param value 模板需要替换的区域
* @param textMap 传入信息集合
* @return 模板需要替换区域信息集合对应值
*/
public static String changeValue(String value, Map<String, String> textMap){
Set<Map.Entry<String, String>> textSets = textMap.entrySet();
for (Map.Entry<String, String> textSet : textSets) {
String key = "${"+textSet.getKey()+"}";
if(value.indexOf(key)!= -1){
value = textSet.getValue();
}
}
if(checkText(value)){
value = "";
}
return value;
}
}