当前位置:   article > 正文

Java导出Excel模版多级联动下拉及导入

Java导出Excel模版多级联动下拉及导入

话不多说 看码

  1. import com.zjy.platform.supplier.param.device.DeviceTemplateImportDTO;
  2. import lombok.Data;
  3. import org.apache.commons.collections.CollectionUtils;
  4. import org.apache.poi.ss.usermodel.*;
  5. import org.apache.poi.ss.util.CellRangeAddressList;
  6. import org.apache.poi.util.IOUtils;
  7. import org.apache.poi.xssf.usermodel.*;
  8. import java.io.File;
  9. import java.io.FileOutputStream;
  10. import java.io.InputStream;
  11. import java.lang.reflect.Field;
  12. import java.lang.reflect.Method;
  13. import java.nio.file.Files;
  14. import java.nio.file.Paths;
  15. import java.util.*;
  16. /**
  17. * <a> 代码千万行 注释第一行 编程不规范 同事两行泪 </a>
  18. *
  19. * @author Enzo
  20. * @date 2024-05-15 15:33
  21. * @description excel导出工具类
  22. */
  23. @Data
  24. public class ExcelExportUtil {
  25. /**
  26. * 导出数据最大行数
  27. */
  28. private static final int MAX_ROWS = 3000;
  29. /**
  30. * 数据页sheet名称
  31. */
  32. private static final String DATA_SHEET_NAME = "dataSheet";
  33. /**
  34. * 标头
  35. */
  36. private List<String> headersList;
  37. /**
  38. * 单选下拉框数据源
  39. */
  40. private List<String> selectDropdownList;
  41. /**
  42. * 单选下拉框列 开始下标 从0开始
  43. */
  44. private int singleChoiceColumnIndex;
  45. /**
  46. * 多级联动下拉数据源
  47. */
  48. private Map<String, List<String>> multilevelDropDownDataSource;
  49. /**
  50. * 多级联动下拉框列 开始下标 从0开始
  51. */
  52. private int multilevelDropDownStartColumn;
  53. /**
  54. * 多级联动数据源
  55. */
  56. private int multilevelDropDownLevel;
  57. public ExcelExportUtil() {
  58. }
  59. /**
  60. * 生成只有标头的模板
  61. *
  62. * @param headersList 标头
  63. */
  64. public ExcelExportUtil(List<String> headersList) {
  65. this.headersList = headersList;
  66. }
  67. /**
  68. * 生成标头 单选 模板
  69. *
  70. * @param headersList 标头
  71. * @param selectDropdownList 单选数据源
  72. * @param singleChoiceColumnIndex 单选开始列 从0计算
  73. */
  74. public ExcelExportUtil(List<String> headersList, List<String> selectDropdownList, int singleChoiceColumnIndex) {
  75. this.headersList = headersList;
  76. this.selectDropdownList = selectDropdownList;
  77. this.singleChoiceColumnIndex = singleChoiceColumnIndex;
  78. }
  79. /**
  80. * 生成标头 多级联动下拉 模板
  81. *
  82. * @param headersList 标头
  83. * @param multilevelDropDownDataSource 多级联动下拉 数据源
  84. * @param multilevelDropDownStartColumn 多级联动下拉 开始列 从0计算
  85. * @param multilevelDropDownLevel 多级联动下拉 层级
  86. */
  87. public ExcelExportUtil(List<String> headersList, Map<String, List<String>> multilevelDropDownDataSource, int multilevelDropDownStartColumn,
  88. int multilevelDropDownLevel) {
  89. this.headersList = headersList;
  90. this.multilevelDropDownDataSource = multilevelDropDownDataSource;
  91. this.multilevelDropDownStartColumn = multilevelDropDownStartColumn;
  92. this.multilevelDropDownLevel = multilevelDropDownLevel;
  93. }
  94. /**
  95. * 生成标头 单选及多级联动下拉 模板
  96. *
  97. * @param headersList 标头
  98. * @param selectDropdownList 单选数据源
  99. * @param singleChoiceColumnIndex 单选开始列 从0计算
  100. * @param multilevelDropDownDataSource 多级联动下拉 数据源
  101. * @param multilevelDropDownStartColumn 多级联动下拉 开始列 从0计算
  102. * @param multilevelDropDownLevel 多级联动下拉 层级
  103. */
  104. public ExcelExportUtil(List<String> headersList, List<String> selectDropdownList, int singleChoiceColumnIndex,
  105. Map<String, List<String>> multilevelDropDownDataSource, int multilevelDropDownStartColumn, int multilevelDropDownLevel) {
  106. this.headersList = headersList;
  107. this.selectDropdownList = selectDropdownList;
  108. this.singleChoiceColumnIndex = singleChoiceColumnIndex;
  109. this.multilevelDropDownDataSource = multilevelDropDownDataSource;
  110. this.multilevelDropDownStartColumn = multilevelDropDownStartColumn;
  111. this.multilevelDropDownLevel = multilevelDropDownLevel;
  112. }
  113. public XSSFWorkbook exportExcel() {
  114. XSSFWorkbook xssfWorkBook = new XSSFWorkbook();
  115. XSSFSheet mainSheet = xssfWorkBook.createSheet(DATA_SHEET_NAME);
  116. //初始化标头
  117. if (CollectionUtils.isNotEmpty(headersList)) {
  118. initHeaders(xssfWorkBook, mainSheet, headersList);
  119. }
  120. //单选框
  121. if (CollectionUtils.isNotEmpty(selectDropdownList)) {
  122. generateDropDownBox(xssfWorkBook, mainSheet, selectDropdownList, singleChoiceColumnIndex);
  123. }
  124. //多级联动
  125. if (!multilevelDropDownDataSource.isEmpty()) {
  126. generateMultilevelDropDownBox(xssfWorkBook, mainSheet, multilevelDropDownDataSource, multilevelDropDownStartColumn,
  127. multilevelDropDownLevel);
  128. }
  129. return xssfWorkBook;
  130. }
  131. /**
  132. * 生成单层下拉框
  133. *
  134. * @param xssfWorkBook 工作簿
  135. * @param mainSheet 主sheet
  136. * @param dataList 下拉数据
  137. */
  138. public void generateDropDownBox(XSSFWorkbook xssfWorkBook, XSSFSheet mainSheet, List<String> dataList, int columnIndex) {
  139. String sheetName = "singleChoiceSheet";
  140. XSSFSheet deviceTypeSheet = xssfWorkBook.createSheet(sheetName);
  141. // 设置sheet是否隐藏
  142. xssfWorkBook.setSheetHidden(xssfWorkBook.getSheetIndex(deviceTypeSheet), true);
  143. writeDropDownData(xssfWorkBook, deviceTypeSheet, dataList, sheetName);
  144. //设置属性下拉
  145. XSSFDataValidationHelper dvHelper = new XSSFDataValidationHelper(mainSheet);
  146. DataValidationConstraint deviceTypeConstraint = dvHelper.createFormulaListConstraint(sheetName);
  147. // 四个参数分别是:起始行、终止行、起始列、终止列 1 (下拉框代表从excel第1+1行开始) 10(下拉框代表从excel第1+10行结束) 5(代表第几列开始,0是第一列,1是第二列) 5(代表第几列结束,0是第一列,1是第二列)
  148. CellRangeAddressList deviceTypeRangeAddressList = new CellRangeAddressList(1, MAX_ROWS, columnIndex, columnIndex);
  149. XSSFDataValidation deviceTypeDataValidation = (XSSFDataValidation) dvHelper.createValidation(deviceTypeConstraint,
  150. deviceTypeRangeAddressList);
  151. deviceTypeDataValidation.setShowErrorBox(true);
  152. deviceTypeDataValidation.createPromptBox("Error", "请选择或输入有效的选项!");
  153. mainSheet.addValidationData(deviceTypeDataValidation);
  154. }
  155. /**
  156. * 生成多级联动下拉框
  157. *
  158. * @param xssfWorkBook 工作簿
  159. * @param assetSheet 主sheet
  160. * @param dropDownDataSource 数据源 Map 父名称 子名称集合
  161. * @param columnStep 开始列
  162. * @param totalLevel 总层级
  163. */
  164. public static void generateMultilevelDropDownBox(XSSFWorkbook xssfWorkBook, XSSFSheet assetSheet, Map<String, List<String>> dropDownDataSource,
  165. int columnStep, int totalLevel) {
  166. String sheetName = "multilevelSheet";
  167. XSSFSheet dataSourceSheet = xssfWorkBook.createSheet(sheetName);
  168. xssfWorkBook.setSheetHidden(xssfWorkBook.getSheetIndex(sheetName), true);
  169. XSSFRow headerRow = dataSourceSheet.createRow(0);
  170. String[] firstValidationArray = null;
  171. boolean firstTime = true;
  172. int columnIndex = 0;
  173. // 构造名称管理器数据源
  174. for (String key : dropDownDataSource.keySet()) {
  175. Cell cell = headerRow.createCell(columnIndex);
  176. cell.setCellValue(key);
  177. if (dropDownDataSource.get(key) == null || dropDownDataSource.get(key).size() == 0) {
  178. continue;
  179. }
  180. ArrayList<String> values = (ArrayList<String>) dropDownDataSource.get(key);
  181. if (firstTime) {
  182. firstValidationArray = values.toArray(new String[0]);
  183. }
  184. int dataRowIndex = 1;
  185. for (String value : values) {
  186. Row row = firstTime ? dataSourceSheet.createRow(dataRowIndex) : dataSourceSheet.getRow(dataRowIndex);
  187. if (row == null) {
  188. row = dataSourceSheet.createRow(dataRowIndex);
  189. }
  190. row.createCell(columnIndex).setCellValue(value);
  191. dataRowIndex++;
  192. }
  193. // 构造名称管理器
  194. char start = (char) ('A' + columnIndex);
  195. int startRow = 2;
  196. String range = "$" + start + "$" + startRow + ":$" + start + "$" + (startRow + values.size() - 1);
  197. Name name = xssfWorkBook.createName();
  198. name.setNameName(key);
  199. String formula = sheetName + "!" + range;
  200. name.setRefersToFormula(formula);
  201. columnIndex++;
  202. firstTime = false;
  203. }
  204. // 第一级设置DataValidation
  205. XSSFDataValidationHelper dvHelper = new XSSFDataValidationHelper(assetSheet);
  206. DataValidationConstraint firstConstraint = dvHelper.createExplicitListConstraint(firstValidationArray);
  207. CellRangeAddressList firstRangeAddressList = new CellRangeAddressList(1, MAX_ROWS, columnStep, columnStep);
  208. DataValidation firstDataValidation = dvHelper.createValidation(firstConstraint, firstRangeAddressList);
  209. firstDataValidation.setShowErrorBox(true);
  210. firstDataValidation.createPromptBox("Error", "请选择有效的选项!");
  211. assetSheet.addValidationData(firstDataValidation);
  212. // 剩下的层级设置DataValidation
  213. for (int i = 1; i < totalLevel; i++) {
  214. char[] offset = new char[1];
  215. offset[0] = (char) ('A' + columnStep + i - 1);
  216. int rowNum = 2;
  217. String formulaString = "INDIRECT($" + new String(offset) + (rowNum) + ")";
  218. XSSFDataValidationConstraint dvConstraint = (XSSFDataValidationConstraint) dvHelper.createFormulaListConstraint(formulaString);
  219. CellRangeAddressList regions = new CellRangeAddressList(1, MAX_ROWS, columnStep + i, columnStep + i);
  220. XSSFDataValidation dataValidationList = (XSSFDataValidation) dvHelper.createValidation(dvConstraint, regions);
  221. dataValidationList.setShowErrorBox(true);
  222. dataValidationList.createPromptBox("Error", "请选择有效的选项!");
  223. assetSheet.addValidationData(dataValidationList);
  224. }
  225. }
  226. /**
  227. * 初始化标头
  228. *
  229. * @param xssfWorkbook 工作簿
  230. * @param mainSheet sheet
  231. * @param headers 标头数据
  232. */
  233. private void initHeaders(XSSFWorkbook xssfWorkbook, XSSFSheet mainSheet, List<String> headers) {
  234. //表头样式
  235. XSSFCellStyle style = xssfWorkbook.createCellStyle();
  236. // 创建一个居中格式
  237. style.setAlignment(HorizontalAlignment.CENTER);
  238. //字体样式
  239. XSSFFont fontStyle = xssfWorkbook.createFont();
  240. fontStyle.setFontName("微软雅黑");
  241. fontStyle.setFontHeightInPoints((short) 12);
  242. fontStyle.setBold(true);
  243. style.setFont(fontStyle);
  244. //生成主内容
  245. //第一个sheet的第一行为标题
  246. XSSFRow rowFirst = mainSheet.createRow(0);
  247. //冻结第一行
  248. mainSheet.createFreezePane(0, 1, 0, 1);
  249. //写标题
  250. for (int i = 0; i < headers.size(); i++) {
  251. //获取第一行的每个单元格
  252. XSSFCell cell = rowFirst.createCell(i);
  253. //设置每列的列宽
  254. mainSheet.setColumnWidth(i, 4000);
  255. //加样式
  256. cell.setCellStyle(style);
  257. //往单元格里写数据
  258. cell.setCellValue(headers.get(i));
  259. }
  260. }
  261. /**
  262. * 循环单个下拉框的数据写入sheet的第A列中
  263. *
  264. * @param xssfWorkBook 工作簿
  265. * @param sheet 主sheet
  266. * @param list 数据源
  267. * @param name sheet名称
  268. */
  269. private void writeDropDownData(XSSFWorkbook xssfWorkBook, XSSFSheet sheet, List<String> list, String name) {
  270. //循环单个下拉框的数据写入sheet的第A列中
  271. for (int i = 0; i < list.size(); i++) {
  272. XSSFRow genderRow = sheet.createRow(i);
  273. genderRow.createCell(0).setCellValue(list.get(i));
  274. }
  275. // 创建数据规则
  276. Name genderName = xssfWorkBook.createName();
  277. genderName.setNameName(name);
  278. genderName.setRefersToFormula(sheet.getSheetName() + "!$A$1:$A$" + list.size());
  279. }
  280. /**
  281. * 输出到硬盘
  282. *
  283. * @param filePath 路径
  284. * @param xssfWorkBook 工作簿
  285. */
  286. public static void writeToFile(String filePath, XSSFWorkbook xssfWorkBook) {
  287. FileOutputStream os = null;
  288. try {
  289. String existName = filePath.substring(0, filePath.lastIndexOf("/"));
  290. File f = new File(existName);
  291. if (!f.exists()) {
  292. f.mkdirs();
  293. }
  294. // 创建可写入的Excel工作簿
  295. File file = new File(filePath);
  296. if (!file.exists()) {
  297. file.createNewFile();
  298. } else {
  299. file.delete();
  300. file.createNewFile();
  301. }
  302. os = new FileOutputStream(filePath);
  303. xssfWorkBook.write(os);
  304. } catch (Exception e) {
  305. e.printStackTrace();
  306. } finally {
  307. IOUtils.closeQuietly(os);
  308. }
  309. }
  310. /**
  311. * excel 导入 读取数据
  312. *
  313. * @param inputStream 文件输入流
  314. * @param beanType 实体类
  315. * @param <T> 实体类泛型
  316. * @return 实体类列表
  317. * @throws Exception io 异常
  318. */
  319. public <T> List<T> importExcel(InputStream inputStream, Class<T> beanType) throws Exception {
  320. Workbook workbook = new XSSFWorkbook(inputStream);
  321. Sheet sheet = workbook.getSheet(DATA_SHEET_NAME);
  322. List<T> result = new ArrayList<>();
  323. for (Row row : sheet) {
  324. if (row.getRowNum() == 0) {
  325. continue;
  326. }
  327. T beanClass = beanType.newInstance();
  328. Field[] fields = beanType.getDeclaredFields();
  329. for (int i = 0; i < fields.length; i++) {
  330. Field field = fields[i];
  331. Cell cell = row.getCell(i, Row.MissingCellPolicy.RETURN_BLANK_AS_NULL);
  332. if (cell != null) {
  333. DataFormatter dataFormatter = new DataFormatter();
  334. String stringCellValue = dataFormatter.formatCellValue(cell);
  335. String filedName = field.getName();
  336. String methodName = "set" + filedName.substring(0, 1).toUpperCase() + filedName.substring(1);
  337. Method method = beanType.getDeclaredMethod(methodName, String.class);
  338. method.invoke(beanClass, stringCellValue);
  339. field.setAccessible(true);
  340. }
  341. }
  342. result.add(beanClass);
  343. }
  344. return result;
  345. }
  346. public static void testExportTemplate() {
  347. String filePath = "D://mnt//设备批量导入模板.xlsx";
  348. //标头
  349. List<String> headers = Arrays.asList("*设备名称", "*设备类型", "*设备编号", "*所属街道", "*所属社区", "*所属小区", "*设备经度", "*设备纬度", "设备型号", "设备安装位置");
  350. //多选下拉
  351. Map<String, List<String>> dropDownDataSource = new LinkedHashMap<>();
  352. List<String> firstAreaNames = new ArrayList<>();
  353. firstAreaNames.add("街道1");
  354. firstAreaNames.add("街道2");
  355. dropDownDataSource.put("一级区域", firstAreaNames);
  356. List<String> secondLevel = new ArrayList<>();
  357. secondLevel.add("社区11");
  358. secondLevel.add("社区12");
  359. dropDownDataSource.put("街道1", secondLevel);
  360. List<String> jiedao2 = new ArrayList<>();
  361. jiedao2.add("社区21");
  362. jiedao2.add("社区22");
  363. dropDownDataSource.put("街道2", jiedao2);
  364. List<String> shequ11 = new ArrayList<>();
  365. shequ11.add("小区111");
  366. shequ11.add("小区112");
  367. dropDownDataSource.put("社区11", shequ11);
  368. List<String> shequ22 = new ArrayList<>();
  369. shequ22.add("小区221");
  370. shequ22.add("小区222");
  371. dropDownDataSource.put("社区22", shequ22);
  372. int multilevelDropDownStartColumn = 3;
  373. int multilevelDropDownLevel = 3;
  374. //单选下拉数据列表
  375. List<String> selectDropdownList = new ArrayList<>();
  376. selectDropdownList.add("视频摄像头");
  377. int singleChoiceColumnIndex = 1;
  378. ExcelExportUtil excelExportUtil = new ExcelExportUtil(headers, selectDropdownList, singleChoiceColumnIndex, dropDownDataSource,
  379. multilevelDropDownStartColumn, multilevelDropDownLevel);
  380. XSSFWorkbook xssfWorkBook = excelExportUtil.exportExcel();
  381. //写入本地磁盘
  382. writeToFile(filePath, xssfWorkBook);
  383. }
  384. private static void testImportExcel() {
  385. ExcelExportUtil excelExportUtil = new ExcelExportUtil();
  386. String filePath = "D://mnt//设备批量导入模板.xlsx";
  387. try {
  388. InputStream inputStream = Files.newInputStream(Paths.get(filePath));
  389. List<DeviceTemplateImportDTO> deviceTemplateImportDTOS = excelExportUtil.importExcel(inputStream, DeviceTemplateImportDTO.class);
  390. System.out.println(deviceTemplateImportDTOS);
  391. } catch (Exception e) {
  392. throw new RuntimeException(e);
  393. }
  394. }
  395. public static void main(String[] args) {
  396. // testExportTemplate();
  397. testImportExcel();
  398. }
  399. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/588084
推荐阅读
相关标签
  

闽ICP备14008679号