完善Excel模板文本格式与资产状态下拉
This commit is contained in:
@@ -2,7 +2,9 @@ package com.ruoyi.info.collection.domain.excel;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.alibaba.excel.annotation.write.style.ColumnWidth;
|
||||
import com.ruoyi.common.annotation.DictDropdown;
|
||||
import com.ruoyi.common.annotation.Required;
|
||||
import com.ruoyi.common.annotation.TextFormat;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
@@ -26,6 +28,7 @@ public class CcdiAssetInfoExcel implements Serializable {
|
||||
@ExcelProperty(value = "关系人证件号*", index = 0)
|
||||
@ColumnWidth(22)
|
||||
@Required
|
||||
@TextFormat
|
||||
private String personId;
|
||||
|
||||
/** 资产大类 */
|
||||
@@ -75,6 +78,7 @@ public class CcdiAssetInfoExcel implements Serializable {
|
||||
/** 资产状态 */
|
||||
@ExcelProperty(value = "资产状态*", index = 9)
|
||||
@ColumnWidth(14)
|
||||
@DictDropdown(dictType = "ccdi_asset_status")
|
||||
@Required
|
||||
private String assetStatus;
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.alibaba.excel.annotation.write.style.ColumnWidth;
|
||||
import com.ruoyi.common.annotation.DictDropdown;
|
||||
import com.ruoyi.common.annotation.Required;
|
||||
import com.ruoyi.common.annotation.TextFormat;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
@@ -63,6 +64,7 @@ public class CcdiStaffFmyRelationExcel implements Serializable {
|
||||
@ExcelProperty(value = "关系人证件号码*", index = 6)
|
||||
@ColumnWidth(20)
|
||||
@Required
|
||||
@TextFormat
|
||||
private String relationCertNo;
|
||||
|
||||
/** 手机号码1 */
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
package com.ruoyi.info.collection.handler;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.alibaba.excel.write.handler.SheetWriteHandler;
|
||||
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
|
||||
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
|
||||
import com.ruoyi.common.annotation.TextFormat;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.poi.ss.usermodel.CellStyle;
|
||||
import org.apache.poi.ss.usermodel.DataFormat;
|
||||
import org.apache.poi.ss.usermodel.Sheet;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Excel文本列写入处理器
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Slf4j
|
||||
public class TextFormatWriteHandler implements SheetWriteHandler {
|
||||
|
||||
private final Class<?> modelClass;
|
||||
|
||||
public TextFormatWriteHandler(Class<?> modelClass) {
|
||||
this.modelClass = modelClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
|
||||
Workbook workbook = writeWorkbookHolder.getWorkbook();
|
||||
Sheet sheet = writeSheetHolder.getSheet();
|
||||
CellStyle textStyle = createTextStyle(workbook);
|
||||
|
||||
for (Field field : getAllFields(modelClass)) {
|
||||
if (field.getAnnotation(TextFormat.class) == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Integer columnIndex = getColumnIndex(field);
|
||||
if (columnIndex == null) {
|
||||
log.warn("字段[{}]没有指定@ExcelProperty的index,跳过文本格式设置", field.getName());
|
||||
continue;
|
||||
}
|
||||
|
||||
sheet.setDefaultColumnStyle(columnIndex, textStyle);
|
||||
log.info("成功将列[{}]设置为文本格式", columnIndex);
|
||||
}
|
||||
}
|
||||
|
||||
private CellStyle createTextStyle(Workbook workbook) {
|
||||
DataFormat dataFormat = workbook.createDataFormat();
|
||||
CellStyle style = workbook.createCellStyle();
|
||||
style.setDataFormat(dataFormat.getFormat("@"));
|
||||
return style;
|
||||
}
|
||||
|
||||
private List<Field> getAllFields(Class<?> clazz) {
|
||||
List<Field> fields = new ArrayList<>();
|
||||
while (clazz != null && clazz != Object.class) {
|
||||
fields.addAll(Arrays.asList(clazz.getDeclaredFields()));
|
||||
clazz = clazz.getSuperclass();
|
||||
}
|
||||
return fields;
|
||||
}
|
||||
|
||||
private Integer getColumnIndex(Field field) {
|
||||
ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
|
||||
if (excelProperty != null && excelProperty.index() >= 0) {
|
||||
return excelProperty.index();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import com.alibaba.excel.write.handler.WriteHandler;
|
||||
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
|
||||
import com.ruoyi.info.collection.handler.DictDropdownWriteHandler;
|
||||
import com.ruoyi.info.collection.handler.RequiredFieldWriteHandler;
|
||||
import com.ruoyi.info.collection.handler.TextFormatWriteHandler;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
@@ -174,6 +175,7 @@ public class EasyExcelUtil {
|
||||
.sheet(sheetName)
|
||||
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
|
||||
.registerWriteHandler(new DictDropdownWriteHandler(clazz))
|
||||
.registerWriteHandler(new TextFormatWriteHandler(clazz))
|
||||
.registerWriteHandler(new RequiredFieldWriteHandler(clazz))
|
||||
.doWrite(List.of());
|
||||
} catch (IOException e) {
|
||||
@@ -200,6 +202,7 @@ public class EasyExcelUtil {
|
||||
.sheet(sheetName)
|
||||
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
|
||||
.registerWriteHandler(new DictDropdownWriteHandler(clazz))
|
||||
.registerWriteHandler(new TextFormatWriteHandler(clazz))
|
||||
.registerWriteHandler(new RequiredFieldWriteHandler(clazz))
|
||||
.doWrite(List.of());
|
||||
} catch (IOException e) {
|
||||
@@ -226,6 +229,7 @@ public class EasyExcelUtil {
|
||||
.sheet(sheetName)
|
||||
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
|
||||
.registerWriteHandler(new DictDropdownWriteHandler(clazz))
|
||||
.registerWriteHandler(new TextFormatWriteHandler(clazz))
|
||||
.registerWriteHandler(new RequiredFieldWriteHandler(clazz))
|
||||
.doWrite(list);
|
||||
} catch (IOException e) {
|
||||
@@ -253,6 +257,7 @@ public class EasyExcelUtil {
|
||||
.sheet(sheetName)
|
||||
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
|
||||
.registerWriteHandler(new DictDropdownWriteHandler(clazz))
|
||||
.registerWriteHandler(new TextFormatWriteHandler(clazz))
|
||||
.registerWriteHandler(new RequiredFieldWriteHandler(clazz))
|
||||
.doWrite(list);
|
||||
} catch (IOException e) {
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
package com.ruoyi.info.collection.utils;
|
||||
|
||||
import com.ruoyi.common.core.domain.entity.SysDictData;
|
||||
import com.ruoyi.common.utils.DictUtils;
|
||||
import com.ruoyi.info.collection.domain.excel.CcdiAssetInfoExcel;
|
||||
import com.ruoyi.info.collection.domain.excel.CcdiStaffFmyRelationExcel;
|
||||
import org.apache.poi.ss.usermodel.CellStyle;
|
||||
import org.apache.poi.ss.usermodel.DataValidation;
|
||||
import org.apache.poi.ss.usermodel.Sheet;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
import org.apache.poi.ss.util.CellRangeAddress;
|
||||
import org.apache.poi.ss.usermodel.WorkbookFactory;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.MockedStatic;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.Mockito.mockStatic;
|
||||
|
||||
class EasyExcelUtilTemplateTest {
|
||||
|
||||
@Test
|
||||
void importTemplateWithDictDropdown_shouldAddAssetStatusDropdownToAssetTemplate() throws Exception {
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
try (MockedStatic<DictUtils> mocked = mockStatic(DictUtils.class)) {
|
||||
mocked.when(() -> DictUtils.getDictCache("ccdi_asset_status"))
|
||||
.thenReturn(List.of(
|
||||
buildDictData("正常"),
|
||||
buildDictData("冻结"),
|
||||
buildDictData("处置中"),
|
||||
buildDictData("报废")
|
||||
));
|
||||
|
||||
EasyExcelUtil.importTemplateWithDictDropdown(response, CcdiAssetInfoExcel.class, "亲属资产信息");
|
||||
}
|
||||
|
||||
try (Workbook workbook = WorkbookFactory.create(new ByteArrayInputStream(response.getContentAsByteArray()))) {
|
||||
Sheet sheet = workbook.getSheetAt(0);
|
||||
assertTrue(hasValidationOnColumn(sheet, 9), "资产状态列应包含下拉校验");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void importTemplateWithDictDropdown_shouldFormatCertificateColumnsAsText() throws Exception {
|
||||
MockHttpServletResponse assetResponse = new MockHttpServletResponse();
|
||||
MockHttpServletResponse familyResponse = new MockHttpServletResponse();
|
||||
|
||||
try (MockedStatic<DictUtils> mocked = mockStatic(DictUtils.class)) {
|
||||
mocked.when(() -> DictUtils.getDictCache("ccdi_asset_status"))
|
||||
.thenReturn(List.of(buildDictData("正常")));
|
||||
mocked.when(() -> DictUtils.getDictCache("ccdi_relation_type"))
|
||||
.thenReturn(List.of(buildDictData("配偶")));
|
||||
mocked.when(() -> DictUtils.getDictCache("ccdi_indiv_gender"))
|
||||
.thenReturn(List.of(buildDictData("男")));
|
||||
mocked.when(() -> DictUtils.getDictCache("ccdi_certificate_type"))
|
||||
.thenReturn(List.of(buildDictData("居民身份证")));
|
||||
|
||||
EasyExcelUtil.importTemplateWithDictDropdown(assetResponse, CcdiAssetInfoExcel.class, "亲属资产信息");
|
||||
EasyExcelUtil.importTemplateWithDictDropdown(familyResponse, CcdiStaffFmyRelationExcel.class, "员工亲属关系信息");
|
||||
}
|
||||
|
||||
try (Workbook assetWorkbook = WorkbookFactory.create(new ByteArrayInputStream(assetResponse.getContentAsByteArray()));
|
||||
Workbook familyWorkbook = WorkbookFactory.create(new ByteArrayInputStream(familyResponse.getContentAsByteArray()))) {
|
||||
assertTextColumn(assetWorkbook.getSheetAt(0), 0);
|
||||
assertTextColumn(familyWorkbook.getSheetAt(0), 6);
|
||||
}
|
||||
}
|
||||
|
||||
private void assertTextColumn(Sheet sheet, int columnIndex) {
|
||||
CellStyle style = sheet.getColumnStyle(columnIndex);
|
||||
assertNotNull(style, "文本列应设置默认样式");
|
||||
assertEquals("@", style.getDataFormatString(), "证件号列应使用文本格式");
|
||||
}
|
||||
|
||||
private boolean hasValidationOnColumn(Sheet sheet, int columnIndex) {
|
||||
for (DataValidation validation : sheet.getDataValidations()) {
|
||||
for (CellRangeAddress address : validation.getRegions().getCellRangeAddresses()) {
|
||||
if (address.getFirstColumn() <= columnIndex && address.getLastColumn() >= columnIndex) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private SysDictData buildDictData(String label) {
|
||||
SysDictData dictData = new SysDictData();
|
||||
dictData.setDictLabel(label);
|
||||
dictData.setDictValue(label);
|
||||
return dictData;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user