Commit 1dbd344ecac56ded48a0ae85a34916b7c759cfac
1 parent
0e7f5057
init: 47项目迁移
Showing
43 changed files
with
4062 additions
and
52 deletions
src/main/java/com/order/erp/common/constant/ServerResultCode.java
src/main/java/com/order/erp/common/excel4j/ExcelUtils.java
0 → 100644
1 | +package com.order.erp.common.excel4j; | |
2 | + | |
3 | +import com.order.erp.common.excel4j.converter.DefaultConvertible; | |
4 | +import com.order.erp.common.excel4j.exceptions.Excel4JException; | |
5 | +import com.order.erp.common.excel4j.exceptions.Excel4jReadException; | |
6 | +import com.order.erp.common.excel4j.handler.ExcelHeader; | |
7 | +import com.order.erp.common.excel4j.handler.SheetTemplate; | |
8 | +import com.order.erp.common.excel4j.handler.SheetTemplateHandler; | |
9 | +import com.order.erp.common.excel4j.utils.Utils; | |
10 | +import com.order.erp.common.excel4j.wrapper.MapSheetWrapper; | |
11 | +import com.order.erp.common.excel4j.wrapper.NoTemplateSheetWrapper; | |
12 | +import com.order.erp.common.excel4j.wrapper.NormalSheetWrapper; | |
13 | +import com.order.erp.common.excel4j.wrapper.SimpleSheetWrapper; | |
14 | +import lombok.extern.slf4j.Slf4j; | |
15 | +import org.apache.commons.csv.CSVFormat; | |
16 | +import org.apache.commons.csv.CSVParser; | |
17 | +import org.apache.commons.csv.CSVPrinter; | |
18 | +import org.apache.commons.csv.CSVRecord; | |
19 | +import org.apache.poi.hssf.usermodel.HSSFWorkbook; | |
20 | +import org.apache.poi.openxml4j.exceptions.InvalidFormatException; | |
21 | +import org.apache.poi.ss.usermodel.*; | |
22 | +import org.apache.poi.xssf.usermodel.XSSFWorkbook; | |
23 | + | |
24 | +import java.io.*; | |
25 | +import java.lang.reflect.Array; | |
26 | +import java.nio.charset.StandardCharsets; | |
27 | +import java.util.ArrayList; | |
28 | +import java.util.Collection; | |
29 | +import java.util.List; | |
30 | +import java.util.Map; | |
31 | + | |
32 | +/** | |
33 | + * Excel4J的主要操作工具类 | |
34 | + * <p> | |
35 | + * 主要包含6大操作类型,并且每个类型都配有一个私有handler:<br> | |
36 | + * 1.读取Excel操作基于注解映射,handler为{@link ExcelUtils#readExcel2ObjectsHandler}<br> | |
37 | + * 2.读取Excel操作无映射,handler为{@link ExcelUtils#readExcel2ObjectsHandler}<br> | |
38 | + * 3.基于模板、注解导出Excel,handler为{@link ExcelUtils#exportExcelByModuleHandler}<br> | |
39 | + * 4.基于模板、注解导出Map数据,handler为{@link ExcelUtils#exportExcelByModuleHandler}<br> | |
40 | + * 5.无模板基于注解导出,handler为{@link ExcelUtils#exportExcelByMapHandler}<br> | |
41 | + * 6.无模板无注解导出,handler为{@link ExcelUtils#exportExcelBySimpleHandler}<br> | |
42 | + * 7.读取CSV操作基于注解,handler为{@link ExcelUtils#readCSVByMapHandler} | |
43 | + * 8.基于注解导出CSV, handler为{@link ExcelUtils#exportCSVByMapHandler} | |
44 | + * <p> | |
45 | + * 另外列举了部分常用的参数格式的方法(不同参数的排列组合实在是太多,没必要完全列出) | |
46 | + * 如遇没有自己需要的参数类型的方法,可通过最全的方法来自行变换<br> | |
47 | + * <p> | |
48 | + */ | |
49 | +@Slf4j | |
50 | +public final class ExcelUtils { | |
51 | + | |
52 | + /** | |
53 | + * 单例模式 | |
54 | + * 通过{@link ExcelUtils#getInstance()}获取对象实例 | |
55 | + */ | |
56 | + private static volatile ExcelUtils excelUtils; | |
57 | + | |
58 | + private ExcelUtils() { | |
59 | + } | |
60 | + | |
61 | + /** | |
62 | + * 双检锁保证单例 | |
63 | + */ | |
64 | + public static ExcelUtils getInstance() { | |
65 | + if (null == excelUtils) { | |
66 | + synchronized (ExcelUtils.class) { | |
67 | + if (null == excelUtils) { | |
68 | + excelUtils = new ExcelUtils(); | |
69 | + } | |
70 | + } | |
71 | + } | |
72 | + return excelUtils; | |
73 | + } | |
74 | + | |
75 | + /*---------------------------------------1.读取Excel操作基于注解映射--------------------------------------------*/ | |
76 | + /* 一. 操作流程 : */ | |
77 | + /* 1) 读取表头信息,与给出的Class类注解匹配 */ | |
78 | + /* 2) 读取表头下面的数据内容, 按行读取, 并映射至java对象 */ | |
79 | + /* 二. 参数说明 */ | |
80 | + /* *) excelPath => 目标Excel路径 */ | |
81 | + /* *) InputStream => 目标Excel文件流 */ | |
82 | + /* *) clazz => java映射对象 */ | |
83 | + /* *) offsetLine => 开始读取行坐标(默认0) */ | |
84 | + /* *) limitLine => 最大读取行数(默认表尾) */ | |
85 | + /* *) sheetIndex => Sheet索引(默认0) */ | |
86 | + | |
87 | + /** | |
88 | + * 读取Excel操作基于注解映射成绑定的java对象 | |
89 | + * | |
90 | + * @param excelPath 待导出Excel的路径 | |
91 | + * @param clazz 待绑定的类(绑定属性注解{@link}) | |
92 | + * @param offsetLine Excel表头行(默认是0) | |
93 | + * @param limitLine 最大读取行数(默认表尾) | |
94 | + * @param sheetIndex Sheet索引(默认0) | |
95 | + * @param <T> 绑定的数据类 | |
96 | + * @return 返回转换为设置绑定的java对象集合 | |
97 | + * @throws Excel4JException 异常 | |
98 | + * @throws IOException 异常 | |
99 | + * @throws InvalidFormatException 异常 | |
100 | + * @author Crab2Died | |
101 | + */ | |
102 | + public <T> List<T> readExcel2Objects(String excelPath, Class<T> clazz, int offsetLine, | |
103 | + int limitLine, int sheetIndex) | |
104 | + throws Excel4JException, IOException, InvalidFormatException { | |
105 | + | |
106 | + try (Workbook workbook = WorkbookFactory.create(new FileInputStream(new File(excelPath)))) { | |
107 | + return readExcel2ObjectsHandler(workbook, clazz, offsetLine, limitLine, sheetIndex); | |
108 | + } | |
109 | + } | |
110 | + | |
111 | + /** | |
112 | + * 读取Excel操作基于注解映射成绑定的java对象 | |
113 | + * | |
114 | + * @param is 待导出Excel的数据流 | |
115 | + * @param clazz 待绑定的类(绑定属性注解{@link }) | |
116 | + * @param offsetLine Excel表头行(默认是0) | |
117 | + * @param limitLine 最大读取行数(默认表尾) | |
118 | + * @param sheetIndex Sheet索引(默认0) | |
119 | + * @param <T> 绑定的数据类 | |
120 | + * @return 返回转换为设置绑定的java对象集合 | |
121 | + * @throws Excel4JException 异常 | |
122 | + * @throws IOException 异常 | |
123 | + * @throws InvalidFormatException 异常 | |
124 | + * @author Crab2Died | |
125 | + */ | |
126 | + public <T> List<T> readExcel2Objects(InputStream is, Class<T> clazz, int offsetLine, | |
127 | + int limitLine, int sheetIndex) | |
128 | + throws Excel4JException, IOException, InvalidFormatException { | |
129 | + | |
130 | + try (Workbook workbook = WorkbookFactory.create(is)) { | |
131 | + return readExcel2ObjectsHandler(workbook, clazz, offsetLine, limitLine, sheetIndex); | |
132 | + } | |
133 | + } | |
134 | + | |
135 | + /** | |
136 | + * 读取Excel操作基于注解映射成绑定的java对象 | |
137 | + * | |
138 | + * @param excelPath 待导出Excel的路径 | |
139 | + * @param clazz 待绑定的类(绑定属性注解{@link }) | |
140 | + * @param offsetLine Excel表头行(默认是0) | |
141 | + * @param sheetIndex Sheet索引(默认0) | |
142 | + * @param <T> 绑定的数据类 | |
143 | + * @return 返回转换为设置绑定的java对象集合 | |
144 | + * @throws Excel4JException 异常 | |
145 | + * @throws IOException 异常 | |
146 | + * @throws InvalidFormatException 异常 | |
147 | + * @author Crab2Died | |
148 | + */ | |
149 | + public <T> List<T> readExcel2Objects(String excelPath, Class<T> clazz, int offsetLine, int sheetIndex) | |
150 | + throws Excel4JException, IOException, InvalidFormatException { | |
151 | + return readExcel2Objects(excelPath, clazz, offsetLine, Integer.MAX_VALUE, sheetIndex); | |
152 | + } | |
153 | + | |
154 | + /** | |
155 | + * 读取Excel操作基于注解映射成绑定的java对象 | |
156 | + * | |
157 | + * @param excelPath 待导出Excel的路径 | |
158 | + * @param clazz 待绑定的类(绑定属性注解{@link }) | |
159 | + * @param sheetIndex Sheet索引(默认0) | |
160 | + * @param <T> 绑定的数据类 | |
161 | + * @return 返回转换为设置绑定的java对象集合 | |
162 | + * @throws Excel4JException 异常 | |
163 | + * @throws IOException 异常 | |
164 | + * @throws InvalidFormatException 异常 | |
165 | + * @author Crab2Died | |
166 | + */ | |
167 | + public <T> List<T> readExcel2Objects(String excelPath, Class<T> clazz, int sheetIndex) | |
168 | + throws Excel4JException, IOException, InvalidFormatException { | |
169 | + return readExcel2Objects(excelPath, clazz, 0, Integer.MAX_VALUE, sheetIndex); | |
170 | + } | |
171 | + | |
172 | + /** | |
173 | + * 读取Excel操作基于注解映射成绑定的java对象 | |
174 | + * | |
175 | + * @param excelPath 待导出Excel的路径 | |
176 | + * @param clazz 待绑定的类(绑定属性注解{@link }) | |
177 | + * @param <T> 绑定的数据类 | |
178 | + * @return 返回转换为设置绑定的java对象集合 | |
179 | + * @throws Excel4JException 异常 | |
180 | + * @throws IOException 异常 | |
181 | + * @throws InvalidFormatException 异常 | |
182 | + * @author Crab2Died | |
183 | + */ | |
184 | + public <T> List<T> readExcel2Objects(String excelPath, Class<T> clazz) | |
185 | + throws Excel4JException, IOException, InvalidFormatException { | |
186 | + return readExcel2Objects(excelPath, clazz, 0, Integer.MAX_VALUE, 0); | |
187 | + } | |
188 | + | |
189 | + /** | |
190 | + * 读取Excel操作基于注解映射成绑定的java对象 | |
191 | + * | |
192 | + * @param is 待导出Excel的数据流 | |
193 | + * @param clazz 待绑定的类(绑定属性注解{@link }) | |
194 | + * @param sheetIndex Sheet索引(默认0) | |
195 | + * @param <T> 绑定的数据类 | |
196 | + * @return 返回转换为设置绑定的java对象集合 | |
197 | + * @throws Excel4JException 异常 | |
198 | + * @throws IOException 异常 | |
199 | + * @throws InvalidFormatException 异常 | |
200 | + * @author Crab2Died | |
201 | + */ | |
202 | + public <T> List<T> readExcel2Objects(InputStream is, Class<T> clazz, int sheetIndex) | |
203 | + throws Excel4JException, IOException, InvalidFormatException { | |
204 | + return readExcel2Objects(is, clazz, 0, Integer.MAX_VALUE, sheetIndex); | |
205 | + } | |
206 | + | |
207 | + /** | |
208 | + * 读取Excel操作基于注解映射成绑定的java对象 | |
209 | + * | |
210 | + * @param is 待导出Excel的数据流 | |
211 | + * @param clazz 待绑定的类(绑定属性注解{@link }) | |
212 | + * @param <T> 绑定的数据类 | |
213 | + * @return 返回转换为设置绑定的java对象集合 | |
214 | + * @throws Excel4JException 异常 | |
215 | + * @throws IOException 异常 | |
216 | + * @throws InvalidFormatException 异常 | |
217 | + * @author Crab2Died | |
218 | + */ | |
219 | + public <T> List<T> readExcel2Objects(InputStream is, Class<T> clazz) | |
220 | + throws Excel4JException, IOException, InvalidFormatException { | |
221 | + return readExcel2Objects(is, clazz, 0, Integer.MAX_VALUE, 0); | |
222 | + } | |
223 | + | |
224 | + private <T> List<T> readExcel2ObjectsHandler(Workbook workbook, Class<T> clazz, int offsetLine, | |
225 | + int limitLine, int sheetIndex) | |
226 | + throws Excel4JException { | |
227 | + | |
228 | + Sheet sheet = workbook.getSheetAt(sheetIndex); | |
229 | + Row row = sheet.getRow(offsetLine); | |
230 | + List<T> list = new ArrayList<>(); | |
231 | + Map<Integer, ExcelHeader> maps = Utils.getHeaderMap(row, clazz); | |
232 | + if (maps == null || maps.size() <= 0) { | |
233 | + throw new Excel4jReadException( | |
234 | + "The Excel format to read is not correct, and check to see if the appropriate rows are set" | |
235 | + ); | |
236 | + } | |
237 | + long maxLine = sheet.getLastRowNum() > ((long) offsetLine + limitLine) ? | |
238 | + ((long) offsetLine + limitLine) : sheet.getLastRowNum(); | |
239 | + | |
240 | + for (int i = offsetLine + 1; i <= maxLine; i++) { | |
241 | + row = sheet.getRow(i); | |
242 | + if (null == row) { | |
243 | + continue; | |
244 | + } | |
245 | + T obj; | |
246 | + try { | |
247 | + obj = clazz.newInstance(); | |
248 | + } catch (InstantiationException | IllegalAccessException e) { | |
249 | + throw new Excel4JException(e); | |
250 | + } | |
251 | + for (Cell cell : row) { | |
252 | + int ci = cell.getColumnIndex(); | |
253 | + ExcelHeader header = maps.get(ci); | |
254 | + if (null == header) { | |
255 | + continue; | |
256 | + } | |
257 | + String val = Utils.getCellValue(cell); | |
258 | + Object value; | |
259 | + String filed = header.getFiled(); | |
260 | + // 读取转换器 | |
261 | + if (null != header.getReadConverter() && | |
262 | + header.getReadConverter().getClass() != DefaultConvertible.class) { | |
263 | + value = header.getReadConverter().execRead(val); | |
264 | + } else { | |
265 | + // 默认转换 | |
266 | + value = Utils.str2TargetClass(val, header.getFiledClazz()); | |
267 | + } | |
268 | + Utils.copyProperty(obj, filed, value); | |
269 | + } | |
270 | + ExcelValidator.validateEntity(obj); | |
271 | + | |
272 | + list.add(obj); | |
273 | + } | |
274 | + return list; | |
275 | + } | |
276 | + | |
277 | + /*---------------------------------------2.读取Excel操作无映射-------------------------------------------------*/ | |
278 | + /* 一. 操作流程 : */ | |
279 | + /* *) 按行读取Excel文件,存储形式为 Cell->String => Row->List<Cell> => Excel->List<Row> */ | |
280 | + /* 二. 参数说明 */ | |
281 | + /* *) excelPath => 目标Excel路径 */ | |
282 | + /* *) InputStream => 目标Excel文件流 */ | |
283 | + /* *) offsetLine => 开始读取行坐标(默认0) */ | |
284 | + /* *) limitLine => 最大读取行数(默认表尾) */ | |
285 | + /* *) sheetIndex => Sheet索引(默认0) */ | |
286 | + | |
287 | + /** | |
288 | + * 读取Excel表格数据,返回{@code List[List[String]]}类型的数据集合 | |
289 | + * | |
290 | + * @param excelPath 待读取Excel的路径 | |
291 | + * @param offsetLine Excel表头行(默认是0) | |
292 | + * @param limitLine 最大读取行数(默认表尾) | |
293 | + * @param sheetIndex Sheet索引(默认0) | |
294 | + * @return 返回{@code List<List<String>>}类型的数据集合 | |
295 | + * @throws IOException 异常 | |
296 | + * @throws InvalidFormatException 异常 | |
297 | + * @author Crab2Died | |
298 | + */ | |
299 | + public List<List<String>> readExcel2List(String excelPath, int offsetLine, int limitLine, int sheetIndex) | |
300 | + throws IOException, InvalidFormatException { | |
301 | + | |
302 | + try (Workbook workbook = WorkbookFactory.create(new FileInputStream(new File(excelPath)))) { | |
303 | + return readExcel2ObjectsHandler(workbook, offsetLine, limitLine, sheetIndex); | |
304 | + } | |
305 | + } | |
306 | + | |
307 | + /** | |
308 | + * 读取Excel表格数据,返回{@code List[List[String]]}类型的数据集合 | |
309 | + * | |
310 | + * @param is 待读取Excel的数据流 | |
311 | + * @param offsetLine Excel表头行(默认是0) | |
312 | + * @param limitLine 最大读取行数(默认表尾) | |
313 | + * @param sheetIndex Sheet索引(默认0) | |
314 | + * @return 返回{@code List<List<String>>}类型的数据集合 | |
315 | + * @throws Excel4JException 异常 | |
316 | + * @throws IOException 异常 | |
317 | + * @throws InvalidFormatException 异常 | |
318 | + * @author Crab2Died | |
319 | + */ | |
320 | + public List<List<String>> readExcel2List(InputStream is, int offsetLine, int limitLine, int sheetIndex) | |
321 | + throws Excel4JException, IOException, InvalidFormatException { | |
322 | + | |
323 | + try (Workbook workbook = WorkbookFactory.create(is)) { | |
324 | + return readExcel2ObjectsHandler(workbook, offsetLine, limitLine, sheetIndex); | |
325 | + } | |
326 | + } | |
327 | + | |
328 | + /** | |
329 | + * 读取Excel表格数据,返回{@code List[List[String]]}类型的数据集合 | |
330 | + * | |
331 | + * @param excelPath 待读取Excel的路径 | |
332 | + * @param offsetLine Excel表头行(默认是0) | |
333 | + * @return 返回{@code List<List<String>>}类型的数据集合 | |
334 | + * @throws IOException 异常 | |
335 | + * @throws InvalidFormatException 异常 | |
336 | + * @author Crab2Died | |
337 | + */ | |
338 | + public List<List<String>> readExcel2List(String excelPath, int offsetLine) | |
339 | + throws IOException, InvalidFormatException { | |
340 | + | |
341 | + try (Workbook workbook = WorkbookFactory.create(new FileInputStream(new File(excelPath)))) { | |
342 | + return readExcel2ObjectsHandler(workbook, offsetLine, Integer.MAX_VALUE, 0); | |
343 | + } | |
344 | + } | |
345 | + | |
346 | + /** | |
347 | + * 读取Excel表格数据,返回{@code List[List[String]]}类型的数据集合 | |
348 | + * | |
349 | + * @param is 待读取Excel的数据流 | |
350 | + * @param offsetLine Excel表头行(默认是0) | |
351 | + * @return 返回{@code List<List<String>>}类型的数据集合 | |
352 | + * @throws IOException 异常 | |
353 | + * @throws InvalidFormatException 异常 | |
354 | + * @author Crab2Died | |
355 | + */ | |
356 | + public List<List<String>> readExcel2List(InputStream is, int offsetLine) | |
357 | + throws IOException, InvalidFormatException { | |
358 | + | |
359 | + try (Workbook workbook = WorkbookFactory.create(is)) { | |
360 | + return readExcel2ObjectsHandler(workbook, offsetLine, Integer.MAX_VALUE, 0); | |
361 | + } | |
362 | + } | |
363 | + | |
364 | + /** | |
365 | + * 读取Excel表格数据,返回{@code List[List[String]]}类型的数据集合 | |
366 | + * | |
367 | + * @param excelPath 待读取Excel的路径 | |
368 | + * @return 返回{@code List<List<String>>}类型的数据集合 | |
369 | + * @throws IOException 异常 | |
370 | + * @throws InvalidFormatException 异常 | |
371 | + * @author Crab2Died | |
372 | + */ | |
373 | + public List<List<String>> readExcel2List(String excelPath) | |
374 | + throws IOException, InvalidFormatException { | |
375 | + | |
376 | + try (Workbook workbook = WorkbookFactory.create(new FileInputStream(new File(excelPath)))) { | |
377 | + return readExcel2ObjectsHandler(workbook, 0, Integer.MAX_VALUE, 0); | |
378 | + } | |
379 | + } | |
380 | + | |
381 | + /** | |
382 | + * 读取Excel表格数据,返回{@code List[List[String]]}类型的数据集合 | |
383 | + * | |
384 | + * @param is 待读取Excel的数据流 | |
385 | + * @return 返回{@code List<List<String>>}类型的数据集合 | |
386 | + * @throws IOException 异常 | |
387 | + * @throws InvalidFormatException 异常 | |
388 | + * @author Crab2Died | |
389 | + */ | |
390 | + public List<List<String>> readExcel2List(InputStream is) | |
391 | + throws IOException, InvalidFormatException { | |
392 | + | |
393 | + try (Workbook workbook = WorkbookFactory.create(is)) { | |
394 | + return readExcel2ObjectsHandler(workbook, 0, Integer.MAX_VALUE, 0); | |
395 | + } | |
396 | + } | |
397 | + | |
398 | + private List<List<String>> readExcel2ObjectsHandler(Workbook workbook, int offsetLine, | |
399 | + int limitLine, int sheetIndex) { | |
400 | + | |
401 | + List<List<String>> list = new ArrayList<>(); | |
402 | + Sheet sheet = workbook.getSheetAt(sheetIndex); | |
403 | + long maxLine = sheet.getLastRowNum() > ((long) offsetLine + limitLine) ? | |
404 | + ((long) offsetLine + limitLine) : sheet.getLastRowNum(); | |
405 | + for (int i = offsetLine; i <= maxLine; i++) { | |
406 | + List<String> rows = new ArrayList<>(); | |
407 | + Row row = sheet.getRow(i); | |
408 | + if (null == row) { | |
409 | + continue; | |
410 | + } | |
411 | + for (Cell cell : row) { | |
412 | + String val = Utils.getCellValue(cell); | |
413 | + rows.add(val); | |
414 | + } | |
415 | + list.add(rows); | |
416 | + } | |
417 | + return list; | |
418 | + } | |
419 | + | |
420 | + | |
421 | + /*-------------------------------------------3.基于模板、注解导出excel------------------------------------------*/ | |
422 | + /* 一. 操作流程 : */ | |
423 | + /* 1) 初始化模板 */ | |
424 | + /* 2) 根据Java对象映射表头 */ | |
425 | + /* 3) 写入数据内容 */ | |
426 | + /* 二. 参数说明 */ | |
427 | + /* *) templatePath => 模板路径 */ | |
428 | + /* *) sheetIndex => Sheet索引(默认0) */ | |
429 | + /* *) data => 导出内容List集合 */ | |
430 | + /* *) extendMap => 扩展内容Map(具体就是key匹配替换模板#key内容) */ | |
431 | + /* *) clazz => 映射对象Class */ | |
432 | + /* *) isWriteHeader => 是否写入表头 */ | |
433 | + /* *) targetPath => 导出文件路径 */ | |
434 | + /* *) os => 导出文件流 */ | |
435 | + | |
436 | + /** | |
437 | + * 基于Excel模板与注解{@link }导出Excel | |
438 | + * | |
439 | + * @param templatePath Excel模板路径 | |
440 | + * @param sheetIndex 指定导出Excel的sheet索引号(默认为0) | |
441 | + * @param data 待导出数据的集合 | |
442 | + * @param extendMap 扩展内容Map数据(具体就是key匹配替换模板#key内容,详情请查阅Excel模板定制方法) | |
443 | + * @param clazz 映射对象Class | |
444 | + * @param isWriteHeader 是否写表头 | |
445 | + * @param targetPath 生成的Excel输出全路径 | |
446 | + * @throws Excel4JException 异常 | |
447 | + * @author Crab2Died | |
448 | + */ | |
449 | + public void exportObjects2Excel(String templatePath, int sheetIndex, List<?> data, | |
450 | + Map<String, String> extendMap, Class clazz, | |
451 | + boolean isWriteHeader, String targetPath) | |
452 | + throws Excel4JException { | |
453 | + | |
454 | + try (SheetTemplate sheetTemplate = exportExcelByModuleHandler | |
455 | + (templatePath, sheetIndex, data, extendMap, clazz, isWriteHeader)) { | |
456 | + sheetTemplate.write2File(targetPath); | |
457 | + } catch (IOException e) { | |
458 | + throw new Excel4JException(e); | |
459 | + } | |
460 | + } | |
461 | + | |
462 | + /** | |
463 | + * 基于Excel模板与注解{@link }导出Excel | |
464 | + * | |
465 | + * @param templatePath Excel模板路径 | |
466 | + * @param sheetIndex 指定导出Excel的sheet索引号(默认为0) | |
467 | + * @param data 待导出数据的集合 | |
468 | + * @param extendMap 扩展内容Map数据(具体就是key匹配替换模板#key内容,详情请查阅Excel模板定制方法) | |
469 | + * @param clazz 映射对象Class | |
470 | + * @param isWriteHeader 是否写表头 | |
471 | + * @param os 生成的Excel待输出数据流 | |
472 | + * @throws Excel4JException 异常 | |
473 | + * @author Crab2Died | |
474 | + */ | |
475 | + public void exportObjects2Excel(String templatePath, int sheetIndex, List<?> data, | |
476 | + Map<String, String> extendMap, Class clazz, | |
477 | + boolean isWriteHeader, OutputStream os) | |
478 | + throws Excel4JException { | |
479 | + | |
480 | + try (SheetTemplate sheetTemplate = exportExcelByModuleHandler | |
481 | + (templatePath, sheetIndex, data, extendMap, clazz, isWriteHeader)) { | |
482 | + sheetTemplate.write2Stream(os); | |
483 | + } catch (IOException e) { | |
484 | + throw new Excel4JException(e); | |
485 | + } | |
486 | + } | |
487 | + | |
488 | + /** | |
489 | + * 基于Excel模板与注解{@link }导出Excel | |
490 | + * | |
491 | + * @param templatePath Excel模板路径 | |
492 | + * @param data 待导出数据的集合 | |
493 | + * @param extendMap 扩展内容Map数据(具体就是key匹配替换模板#key内容,详情请查阅Excel模板定制方法) | |
494 | + * @param clazz 映射对象Class | |
495 | + * @param isWriteHeader 是否写表头 | |
496 | + * @param targetPath 生成的Excel输出全路径 | |
497 | + * @throws Excel4JException 异常 | |
498 | + * @author Crab2Died | |
499 | + */ | |
500 | + public void exportObjects2Excel(String templatePath, List<?> data, Map<String, String> extendMap, | |
501 | + Class clazz, boolean isWriteHeader, String targetPath) | |
502 | + throws Excel4JException { | |
503 | + | |
504 | + exportObjects2Excel(templatePath, 0, data, extendMap, clazz, isWriteHeader, targetPath); | |
505 | + } | |
506 | + | |
507 | + /** | |
508 | + * 基于Excel模板与注解{@link }导出Excel | |
509 | + * | |
510 | + * @param templatePath Excel模板路径 | |
511 | + * @param data 待导出数据的集合 | |
512 | + * @param extendMap 扩展内容Map数据(具体就是key匹配替换模板#key内容,详情请查阅Excel模板定制方法) | |
513 | + * @param clazz 映射对象Class | |
514 | + * @param isWriteHeader 是否写表头 | |
515 | + * @param os 生成的Excel待输出数据流 | |
516 | + * @throws Excel4JException 异常 | |
517 | + * @author Crab2Died | |
518 | + */ | |
519 | + public void exportObjects2Excel(String templatePath, List<?> data, Map<String, String> extendMap, | |
520 | + Class clazz, boolean isWriteHeader, OutputStream os) | |
521 | + throws Excel4JException { | |
522 | + | |
523 | + exportObjects2Excel(templatePath, 0, data, extendMap, clazz, isWriteHeader, os); | |
524 | + } | |
525 | + | |
526 | + /** | |
527 | + * 基于Excel模板与注解{@link }导出Excel | |
528 | + * | |
529 | + * @param templatePath Excel模板路径 | |
530 | + * @param data 待导出数据的集合 | |
531 | + * @param extendMap 扩展内容Map数据(具体就是key匹配替换模板#key内容,详情请查阅Excel模板定制方法) | |
532 | + * @param clazz 映射对象Class | |
533 | + * @param targetPath 生成的Excel输出全路径 | |
534 | + * @throws Excel4JException 异常 | |
535 | + * @author Crab2Died | |
536 | + */ | |
537 | + public void exportObjects2Excel(String templatePath, List<?> data, Map<String, String> extendMap, | |
538 | + Class clazz, String targetPath) | |
539 | + throws Excel4JException { | |
540 | + | |
541 | + exportObjects2Excel(templatePath, 0, data, extendMap, clazz, true, targetPath); | |
542 | + } | |
543 | + | |
544 | + /** | |
545 | + * 基于Excel模板与注解{@link }导出Excel | |
546 | + * | |
547 | + * @param templatePath Excel模板路径 | |
548 | + * @param data 待导出数据的集合 | |
549 | + * @param extendMap 扩展内容Map数据(具体就是key匹配替换模板#key内容,详情请查阅Excel模板定制方法) | |
550 | + * @param clazz 映射对象Class | |
551 | + * @param os 生成的Excel待输出数据流 | |
552 | + * @throws Excel4JException 异常 | |
553 | + * @author Crab2Died | |
554 | + */ | |
555 | + public void exportObjects2Excel(String templatePath, List<?> data, Map<String, String> extendMap, | |
556 | + Class clazz, OutputStream os) | |
557 | + throws Excel4JException { | |
558 | + | |
559 | + exportObjects2Excel(templatePath, 0, data, extendMap, clazz, true, os); | |
560 | + } | |
561 | + | |
562 | + /** | |
563 | + * 基于Excel模板与注解{@link }导出Excel | |
564 | + * | |
565 | + * @param templatePath Excel模板路径 | |
566 | + * @param data 待导出数据的集合 | |
567 | + * @param clazz 映射对象Class | |
568 | + * @param targetPath 生成的Excel输出全路径 | |
569 | + * @throws Excel4JException 异常 | |
570 | + * @author Crab2Died | |
571 | + */ | |
572 | + public void exportObjects2Excel(String templatePath, List<?> data, Class clazz, String targetPath) | |
573 | + throws Excel4JException { | |
574 | + | |
575 | + exportObjects2Excel(templatePath, 0, data, null, clazz, true, targetPath); | |
576 | + } | |
577 | + | |
578 | + /** | |
579 | + * 基于Excel模板与注解{@link }导出Excel | |
580 | + * | |
581 | + * @param templatePath Excel模板路径 | |
582 | + * @param data 待导出数据的集合 | |
583 | + * @param clazz 映射对象Class | |
584 | + * @param os 生成的Excel待输出数据流 | |
585 | + * @throws Excel4JException 异常 | |
586 | + * @author Crab2Died | |
587 | + */ | |
588 | + public void exportObjects2Excel(String templatePath, List<?> data, Class clazz, OutputStream os) | |
589 | + throws Excel4JException { | |
590 | + | |
591 | + exportObjects2Excel(templatePath, 0, data, null, clazz, true, os); | |
592 | + } | |
593 | + | |
594 | + // 单sheet导出 | |
595 | + private SheetTemplate exportExcelByModuleHandler(String templatePath, | |
596 | + int sheetIndex, | |
597 | + List<?> data, | |
598 | + Map<String, String> extendMap, | |
599 | + Class clazz, | |
600 | + boolean isWriteHeader) | |
601 | + throws Excel4JException { | |
602 | + | |
603 | + SheetTemplate template = SheetTemplateHandler.sheetTemplateBuilder(templatePath); | |
604 | + generateSheet(sheetIndex, data, extendMap, clazz, isWriteHeader, template); | |
605 | + return template; | |
606 | + } | |
607 | + | |
608 | + /** | |
609 | + * 基于Excel模板与注解{@link }导出多sheet的Excel | |
610 | + * | |
611 | + * @param sheetWrappers sheet包装类 | |
612 | + * @param templatePath Excel模板路径 | |
613 | + * @param targetPath 导出Excel文件路径 | |
614 | + * @throws Excel4JException 异常 | |
615 | + */ | |
616 | + public void normalSheet2Excel(List<NormalSheetWrapper> sheetWrappers, String templatePath, String targetPath) | |
617 | + throws Excel4JException { | |
618 | + | |
619 | + try (SheetTemplate sheetTemplate = exportExcelByModuleHandler(templatePath, sheetWrappers)) { | |
620 | + sheetTemplate.write2File(targetPath); | |
621 | + } catch (IOException e) { | |
622 | + throw new Excel4JException(e); | |
623 | + } | |
624 | + } | |
625 | + | |
626 | + /** | |
627 | + * 基于Excel模板与注解{@link }导出多sheet的Excel | |
628 | + * | |
629 | + * @param sheetWrappers sheet包装类 | |
630 | + * @param templatePath Excel模板路径 | |
631 | + * @param os 生成的Excel待输出数据流 | |
632 | + * @throws Excel4JException 异常 | |
633 | + */ | |
634 | + public void normalSheet2Excel(List<NormalSheetWrapper> sheetWrappers, String templatePath, OutputStream os) | |
635 | + throws Excel4JException { | |
636 | + | |
637 | + try (SheetTemplate sheetTemplate = exportExcelByModuleHandler(templatePath, sheetWrappers)) { | |
638 | + sheetTemplate.write2Stream(os); | |
639 | + } catch (IOException e) { | |
640 | + throw new Excel4JException(e); | |
641 | + } | |
642 | + } | |
643 | + | |
644 | + // 多sheet导出 | |
645 | + private SheetTemplate exportExcelByModuleHandler(String templatePath, | |
646 | + List<NormalSheetWrapper> sheets) | |
647 | + throws Excel4JException { | |
648 | + | |
649 | + SheetTemplate template = SheetTemplateHandler.sheetTemplateBuilder(templatePath); | |
650 | + for (NormalSheetWrapper sheet : sheets) { | |
651 | + generateSheet(sheet.getSheetIndex(), sheet.getData(), sheet.getExtendMap(), sheet.getClazz(), | |
652 | + sheet.isWriteHeader(), template); | |
653 | + } | |
654 | + return template; | |
655 | + } | |
656 | + | |
657 | + // 生成sheet数据 | |
658 | + private void generateSheet(int sheetIndex, List<?> data, Map<String, String> extendMap, Class clazz, | |
659 | + boolean isWriteHeader, SheetTemplate template) | |
660 | + throws Excel4JException { | |
661 | + | |
662 | + SheetTemplateHandler.loadTemplate(template, sheetIndex); | |
663 | + SheetTemplateHandler.extendData(template, extendMap); | |
664 | + List<ExcelHeader> headers = Utils.getHeaderList(clazz); | |
665 | + if (isWriteHeader) { | |
666 | + // 写标题 | |
667 | + SheetTemplateHandler.createNewRow(template); | |
668 | + for (ExcelHeader header : headers) { | |
669 | + SheetTemplateHandler.createCell(template, header.getTitle(), null); | |
670 | + } | |
671 | + } | |
672 | + | |
673 | + for (Object object : data) { | |
674 | + SheetTemplateHandler.createNewRow(template); | |
675 | + SheetTemplateHandler.insertSerial(template, null); | |
676 | + for (ExcelHeader header : headers) { | |
677 | + SheetTemplateHandler.createCell(template, Utils.getProperty(object, header.getFiled(), | |
678 | + header.getWriteConverter()), null); | |
679 | + } | |
680 | + } | |
681 | + } | |
682 | + | |
683 | + | |
684 | + /*-------------------------------------4.基于模板、注解导出Map数据----------------------------------------------*/ | |
685 | + /* 一. 操作流程 : */ | |
686 | + /* 1) 初始化模板 */ | |
687 | + /* 2) 根据Java对象映射表头 */ | |
688 | + /* 3) 写入数据内容 */ | |
689 | + /* 二. 参数说明 */ | |
690 | + /* *) templatePath => 模板路径 */ | |
691 | + /* *) sheetIndex => Sheet索引(默认0) */ | |
692 | + /* *) data => 导出内容Map集合 */ | |
693 | + /* *) extendMap => 扩展内容Map(具体就是key匹配替换模板#key内容) */ | |
694 | + /* *) clazz => 映射对象Class */ | |
695 | + /* *) isWriteHeader => 是否写入表头 */ | |
696 | + /* *) targetPath => 导出文件路径 */ | |
697 | + /* *) os => 导出文件流 */ | |
698 | + | |
699 | + /** | |
700 | + * 基于模板、注解导出{@code Map[String, List[?]]}类型数据 | |
701 | + * 模板定制详见定制说明 | |
702 | + * | |
703 | + * @param templatePath Excel模板路径 | |
704 | + * @param sheetIndex 指定导出Excel的sheet索引号(默认为0) | |
705 | + * @param data 待导出的{@code Map<String, List<?>>}类型数据 | |
706 | + * @param extendMap 扩展内容Map数据(具体就是key匹配替换模板#key内容,详情请查阅Excel模板定制方法) | |
707 | + * @param clazz 映射对象Class | |
708 | + * @param isWriteHeader 是否写入表头 | |
709 | + * @param targetPath 生成的Excel输出全路径 | |
710 | + * @throws Excel4JException 异常 | |
711 | + * @author Crab2Died | |
712 | + */ | |
713 | + public void exportMap2Excel(String templatePath, int sheetIndex, Map<String, List<?>> data, | |
714 | + Map<String, String> extendMap, Class clazz, | |
715 | + boolean isWriteHeader, String targetPath) | |
716 | + throws Excel4JException { | |
717 | + | |
718 | + try (SheetTemplate sheetTemplate = exportExcelByMapHandler(templatePath, sheetIndex, data, extendMap, clazz, | |
719 | + isWriteHeader)) { | |
720 | + sheetTemplate.write2File(targetPath); | |
721 | + } catch (IOException e) { | |
722 | + throw new Excel4JException(e); | |
723 | + } | |
724 | + } | |
725 | + | |
726 | + /** | |
727 | + * 基于模板、注解导出{@code Map[String, List[?]]}类型数据 | |
728 | + * 模板定制详见定制说明 | |
729 | + * | |
730 | + * @param templatePath Excel模板路径 | |
731 | + * @param sheetIndex 指定导出Excel的sheet索引号(默认为0) | |
732 | + * @param data 待导出的{@code Map<String, List<?>>}类型数据 | |
733 | + * @param extendMap 扩展内容Map数据(具体就是key匹配替换模板#key内容,详情请查阅Excel模板定制方法) | |
734 | + * @param clazz 映射对象Class | |
735 | + * @param isWriteHeader 是否写入表头 | |
736 | + * @param os 生成的Excel待输出数据流 | |
737 | + * @throws Excel4JException 异常 | |
738 | + * @author Crab2Died | |
739 | + */ | |
740 | + public void exportMap2Excel(String templatePath, int sheetIndex, Map<String, List<?>> data, | |
741 | + Map<String, String> extendMap, Class clazz, boolean isWriteHeader, OutputStream os) | |
742 | + throws Excel4JException { | |
743 | + | |
744 | + try (SheetTemplate sheetTemplate = exportExcelByMapHandler(templatePath, sheetIndex, data, extendMap, clazz, | |
745 | + isWriteHeader)) { | |
746 | + sheetTemplate.write2Stream(os); | |
747 | + } catch (IOException e) { | |
748 | + throw new Excel4JException(e); | |
749 | + } | |
750 | + } | |
751 | + | |
752 | + /** | |
753 | + * 基于模板、注解导出{@code Map[String, List[?]]}类型数据 | |
754 | + * 模板定制详见定制说明 | |
755 | + * | |
756 | + * @param templatePath Excel模板路径 | |
757 | + * @param data 待导出的{@code Map<String, List<?>>}类型数据 | |
758 | + * @param extendMap 扩展内容Map数据(具体就是key匹配替换模板#key内容,详情请查阅Excel模板定制方法) | |
759 | + * @param clazz 映射对象Class | |
760 | + * @param targetPath 生成的Excel输出全路径 | |
761 | + * @throws Excel4JException 异常 | |
762 | + * @author Crab2Died | |
763 | + */ | |
764 | + public void exportMap2Excel(String templatePath, Map<String, List<?>> data, | |
765 | + Map<String, String> extendMap, Class clazz, String targetPath) | |
766 | + throws Excel4JException { | |
767 | + | |
768 | + try (SheetTemplate sheetTemplate = exportExcelByMapHandler(templatePath, 0, data, extendMap, clazz, true)) { | |
769 | + sheetTemplate.write2File(targetPath); | |
770 | + } catch (IOException e) { | |
771 | + throw new Excel4JException(e); | |
772 | + } | |
773 | + } | |
774 | + | |
775 | + /** | |
776 | + * 基于模板、注解导出{@code Map[String, List[?]]}类型数据 | |
777 | + * 模板定制详见定制说明 | |
778 | + * | |
779 | + * @param templatePath Excel模板路径 | |
780 | + * @param data 待导出的{@code Map<String, List<?>>}类型数据 | |
781 | + * @param extendMap 扩展内容Map数据(具体就是key匹配替换模板#key内容,详情请查阅Excel模板定制方法) | |
782 | + * @param clazz 映射对象Class | |
783 | + * @param os 生成的Excel待输出数据流 | |
784 | + * @throws Excel4JException 异常 | |
785 | + * @author Crab2Died | |
786 | + */ | |
787 | + public void exportMap2Excel(String templatePath, Map<String, List<?>> data, | |
788 | + Map<String, String> extendMap, Class clazz, OutputStream os) | |
789 | + throws Excel4JException { | |
790 | + | |
791 | + try (SheetTemplate sheetTemplate = exportExcelByMapHandler(templatePath, 0, data, extendMap, clazz, true)) { | |
792 | + sheetTemplate.write2Stream(os); | |
793 | + } catch (IOException e) { | |
794 | + throw new Excel4JException(e); | |
795 | + } | |
796 | + } | |
797 | + | |
798 | + /** | |
799 | + * 基于模板、注解导出{@code Map[String, List[?]]}类型数据 | |
800 | + * 模板定制详见定制说明 | |
801 | + * | |
802 | + * @param templatePath Excel模板路径 | |
803 | + * @param data 待导出的{@code Map<String, List<?>>}类型数据 | |
804 | + * @param clazz 映射对象Class | |
805 | + * @param targetPath 生成的Excel输出全路径 | |
806 | + * @throws Excel4JException 异常 | |
807 | + * @author Crab2Died | |
808 | + */ | |
809 | + public void exportMap2Excel(String templatePath, Map<String, List<?>> data, | |
810 | + Class clazz, String targetPath) | |
811 | + throws Excel4JException { | |
812 | + | |
813 | + try (SheetTemplate sheetTemplate = exportExcelByMapHandler(templatePath, 0, data, null, clazz, true)) { | |
814 | + sheetTemplate.write2File(targetPath); | |
815 | + } catch (IOException e) { | |
816 | + throw new Excel4JException(e); | |
817 | + } | |
818 | + } | |
819 | + | |
820 | + /** | |
821 | + * 基于模板、注解导出{@code Map[String, List[?]]}类型数据 | |
822 | + * 模板定制详见定制说明 | |
823 | + * | |
824 | + * @param templatePath Excel模板路径 | |
825 | + * @param data 待导出的{@code Map<String, List<?>>}类型数据 | |
826 | + * @param clazz 映射对象Class | |
827 | + * @param os 生成的Excel待输出数据流 | |
828 | + * @throws Excel4JException 异常 | |
829 | + * @author Crab2Died | |
830 | + */ | |
831 | + public void exportMap2Excel(String templatePath, Map<String, List<?>> data, | |
832 | + Class clazz, OutputStream os) | |
833 | + throws Excel4JException { | |
834 | + | |
835 | + try (SheetTemplate sheetTemplate = exportExcelByMapHandler(templatePath, 0, data, null, clazz, true)) { | |
836 | + sheetTemplate.write2Stream(os); | |
837 | + } catch (IOException e) { | |
838 | + throw new Excel4JException(e); | |
839 | + } | |
840 | + } | |
841 | + | |
842 | + // 单sheet导出 | |
843 | + private SheetTemplate exportExcelByMapHandler(String templatePath, | |
844 | + int sheetIndex, | |
845 | + Map<String, List<?>> data, | |
846 | + Map<String, String> extendMap, | |
847 | + Class clazz, | |
848 | + boolean isWriteHeader) | |
849 | + throws Excel4JException { | |
850 | + | |
851 | + // 加载模板 | |
852 | + SheetTemplate template = SheetTemplateHandler.sheetTemplateBuilder(templatePath); | |
853 | + | |
854 | + // 生成sheet | |
855 | + generateSheet(template, sheetIndex, data, extendMap, clazz, isWriteHeader); | |
856 | + | |
857 | + return template; | |
858 | + } | |
859 | + | |
860 | + /** | |
861 | + * 基于模板、注解的多sheet导出{@code Map[String, List[?]]}类型数据 | |
862 | + * 模板定制详见定制说明 | |
863 | + * | |
864 | + * @param sheetWrappers sheet包装类 | |
865 | + * @param templatePath Excel模板 | |
866 | + * @param targetPath 导出Excel路径 | |
867 | + * @throws Excel4JException 异常 | |
868 | + */ | |
869 | + public void mapSheet2Excel(List<MapSheetWrapper> sheetWrappers, String templatePath, String targetPath) | |
870 | + throws Excel4JException { | |
871 | + | |
872 | + try (SheetTemplate sheetTemplate = exportExcelByMapHandler(sheetWrappers, templatePath)) { | |
873 | + sheetTemplate.write2File(targetPath); | |
874 | + } catch (IOException e) { | |
875 | + throw new Excel4JException(e); | |
876 | + } | |
877 | + } | |
878 | + | |
879 | + /** | |
880 | + * 基于模板、注解的多sheet导出{@code Map[String, List[?]]}类型数据 | |
881 | + * 模板定制详见定制说明 | |
882 | + * | |
883 | + * @param sheetWrappers sheet包装类 | |
884 | + * @param templatePath Excel模板 | |
885 | + * @param os 输出流 | |
886 | + * @throws Excel4JException 异常 | |
887 | + */ | |
888 | + public void mapSheet2Excel(List<MapSheetWrapper> sheetWrappers, String templatePath, OutputStream os) | |
889 | + throws Excel4JException { | |
890 | + | |
891 | + try (SheetTemplate sheetTemplate = exportExcelByMapHandler(sheetWrappers, templatePath)) { | |
892 | + sheetTemplate.write2Stream(os); | |
893 | + } catch (IOException e) { | |
894 | + throw new Excel4JException(e); | |
895 | + } | |
896 | + } | |
897 | + | |
898 | + // 多sheet导出 | |
899 | + private SheetTemplate exportExcelByMapHandler(List<MapSheetWrapper> sheetWrappers, | |
900 | + String templatePath) | |
901 | + throws Excel4JException { | |
902 | + | |
903 | + // 加载模板 | |
904 | + SheetTemplate template = SheetTemplateHandler.sheetTemplateBuilder(templatePath); | |
905 | + | |
906 | + // 多sheet生成 | |
907 | + for (MapSheetWrapper sheet : sheetWrappers) { | |
908 | + generateSheet(template, | |
909 | + sheet.getSheetIndex(), | |
910 | + sheet.getData(), | |
911 | + sheet.getExtendMap(), | |
912 | + sheet.getClazz(), | |
913 | + sheet.isWriteHeader() | |
914 | + ); | |
915 | + } | |
916 | + | |
917 | + return template; | |
918 | + } | |
919 | + | |
920 | + // sheet生成 | |
921 | + private void generateSheet(SheetTemplate template, int sheetIndex, | |
922 | + Map<String, List<?>> data, Map<String, String> extendMap, | |
923 | + Class clazz, boolean isWriteHeader) | |
924 | + throws Excel4JException { | |
925 | + | |
926 | + SheetTemplateHandler.loadTemplate(template, sheetIndex); | |
927 | + SheetTemplateHandler.extendData(template, extendMap); | |
928 | + List<ExcelHeader> headers = Utils.getHeaderList(clazz); | |
929 | + if (isWriteHeader) { | |
930 | + // 写标题 | |
931 | + SheetTemplateHandler.createNewRow(template); | |
932 | + for (ExcelHeader header : headers) { | |
933 | + SheetTemplateHandler.createCell(template, header.getTitle(), null); | |
934 | + } | |
935 | + } | |
936 | + for (Map.Entry<String, List<?>> entry : data.entrySet()) { | |
937 | + for (Object object : entry.getValue()) { | |
938 | + SheetTemplateHandler.createNewRow(template); | |
939 | + SheetTemplateHandler.insertSerial(template, entry.getKey()); | |
940 | + for (ExcelHeader header : headers) { | |
941 | + SheetTemplateHandler.createCell(template, | |
942 | + Utils.getProperty(object, header.getFiled(), header.getWriteConverter()), | |
943 | + entry.getKey() | |
944 | + ); | |
945 | + } | |
946 | + } | |
947 | + } | |
948 | + } | |
949 | + | |
950 | + | |
951 | + /*--------------------------------------5.无模板基于注解导出---------------------------------------------------*/ | |
952 | + /* 一. 操作流程 : */ | |
953 | + /* 1) 根据Java对象映射表头 */ | |
954 | + /* 2) 写入数据内容 */ | |
955 | + /* 二. 参数说明 */ | |
956 | + /* *) data => 导出内容List集合 */ | |
957 | + /* *) isWriteHeader => 是否写入表头 */ | |
958 | + /* *) sheetName => Sheet索引名(默认0) */ | |
959 | + /* *) clazz => 映射对象Class */ | |
960 | + /* *) isXSSF => 是否Excel2007及以上版本 */ | |
961 | + /* *) targetPath => 导出文件路径 */ | |
962 | + /* *) os => 导出文件流 */ | |
963 | + | |
964 | + /** | |
965 | + * 无模板、基于注解的数据导出 | |
966 | + * | |
967 | + * @param data 待导出数据 | |
968 | + * @param clazz {@link }映射对象Class | |
969 | + * @param isWriteHeader 是否写入表头 | |
970 | + * @param sheetName 指定导出Excel的sheet名称 | |
971 | + * @param isXSSF 导出的Excel是否为Excel2007及以上版本(默认是) | |
972 | + * @param targetPath 生成的Excel输出全路径 | |
973 | + * @throws Excel4JException 异常 | |
974 | + * @throws IOException 异常 | |
975 | + * @author Crab2Died | |
976 | + */ | |
977 | + public void exportObjects2Excel(List<?> data, Class clazz, boolean isWriteHeader, | |
978 | + String sheetName, boolean isXSSF, String targetPath) | |
979 | + throws Excel4JException, IOException { | |
980 | + | |
981 | + try (FileOutputStream fos = new FileOutputStream(targetPath); | |
982 | + Workbook workbook = exportExcelNoTemplateHandler(data, clazz, isWriteHeader, sheetName, isXSSF)) { | |
983 | + workbook.write(fos); | |
984 | + } | |
985 | + } | |
986 | + | |
987 | + /** | |
988 | + * 无模板、基于注解的数据导出 | |
989 | + * | |
990 | + * @param data 待导出数据 | |
991 | + * @param clazz {@link }映射对象Class | |
992 | + * @param isWriteHeader 是否写入表头 | |
993 | + * @param sheetName 指定导出Excel的sheet名称 | |
994 | + * @param isXSSF 导出的Excel是否为Excel2007及以上版本(默认是) | |
995 | + * @param os 生成的Excel待输出数据流 | |
996 | + * @throws Excel4JException 异常 | |
997 | + * @throws IOException 异常 | |
998 | + * @author Crab2Died | |
999 | + */ | |
1000 | + public void exportObjects2Excel(List<?> data, Class clazz, boolean isWriteHeader, | |
1001 | + String sheetName, boolean isXSSF, OutputStream os) | |
1002 | + throws Excel4JException, IOException { | |
1003 | + | |
1004 | + try (Workbook workbook = exportExcelNoTemplateHandler(data, clazz, isWriteHeader, sheetName, isXSSF)) { | |
1005 | + workbook.write(os); | |
1006 | + } | |
1007 | + } | |
1008 | + | |
1009 | + /** | |
1010 | + * 无模板、基于注解的数据导出 | |
1011 | + * | |
1012 | + * @param data 待导出数据 | |
1013 | + * @param clazz {@link }映射对象Class | |
1014 | + * @param isWriteHeader 是否写入表头 | |
1015 | + * @param targetPath 生成的Excel输出全路径 | |
1016 | + * @throws Excel4JException 异常 | |
1017 | + * @throws IOException 异常 | |
1018 | + * @author Crab2Died | |
1019 | + */ | |
1020 | + public void exportObjects2Excel(List<?> data, Class clazz, boolean isWriteHeader, String targetPath) | |
1021 | + throws Excel4JException, IOException { | |
1022 | + | |
1023 | + try (FileOutputStream fos = new FileOutputStream(targetPath); | |
1024 | + Workbook workbook = exportExcelNoTemplateHandler(data, clazz, isWriteHeader, null, true)) { | |
1025 | + workbook.write(fos); | |
1026 | + } | |
1027 | + } | |
1028 | + | |
1029 | + /** | |
1030 | + * 无模板、基于注解的数据导出 | |
1031 | + * | |
1032 | + * @param data 待导出数据 | |
1033 | + * @param clazz {@link }映射对象Class | |
1034 | + * @param isWriteHeader 是否写入表头 | |
1035 | + * @param os 生成的Excel待输出数据流 | |
1036 | + * @throws Excel4JException 异常 | |
1037 | + * @throws IOException 异常 | |
1038 | + * @author Crab2Died | |
1039 | + */ | |
1040 | + public void exportObjects2Excel(List<?> data, Class clazz, boolean isWriteHeader, OutputStream os) | |
1041 | + throws Excel4JException, IOException { | |
1042 | + | |
1043 | + try (Workbook workbook = exportExcelNoTemplateHandler(data, clazz, isWriteHeader, null, true)) { | |
1044 | + workbook.write(os); | |
1045 | + } | |
1046 | + } | |
1047 | + | |
1048 | + /** | |
1049 | + * 无模板、基于注解的数据导出 | |
1050 | + * | |
1051 | + * @param data 待导出数据 | |
1052 | + * @param clazz {@link }映射对象Class | |
1053 | + * @param os 生成的Excel待输出数据流 | |
1054 | + * @throws Excel4JException 异常 | |
1055 | + * @throws IOException 异常 | |
1056 | + * @author Crab2Died | |
1057 | + */ | |
1058 | + public void exportObjects2Excel(List<?> data, Class clazz, OutputStream os) | |
1059 | + throws Excel4JException, IOException { | |
1060 | + | |
1061 | + try (Workbook workbook = exportExcelNoTemplateHandler(data, clazz, true, null, true)) { | |
1062 | + workbook.write(os); | |
1063 | + } | |
1064 | + } | |
1065 | + | |
1066 | + /** | |
1067 | + * 无模板、基于注解的数据导出 | |
1068 | + * | |
1069 | + * @param data 待导出数据 | |
1070 | + * @param clazz {@link }映射对象Class | |
1071 | + * @param targetPath 生成的Excel输出全路径 | |
1072 | + * @throws Excel4JException 异常 | |
1073 | + * @throws IOException 异常 | |
1074 | + * @author Crab2Died | |
1075 | + */ | |
1076 | + public void exportObjects2Excel(List<?> data, Class clazz, String targetPath) | |
1077 | + throws Excel4JException, IOException { | |
1078 | + | |
1079 | + try (FileOutputStream fos = new FileOutputStream(targetPath); | |
1080 | + Workbook workbook = exportExcelNoTemplateHandler(data, clazz, true, null, true)) { | |
1081 | + workbook.write(fos); | |
1082 | + } | |
1083 | + } | |
1084 | + | |
1085 | + // 单sheet数据导出 | |
1086 | + private Workbook exportExcelNoTemplateHandler(List<?> data, Class clazz, boolean isWriteHeader, | |
1087 | + String sheetName, boolean isXSSF) | |
1088 | + throws Excel4JException { | |
1089 | + | |
1090 | + Workbook workbook; | |
1091 | + if (isXSSF) { | |
1092 | + workbook = new XSSFWorkbook(); | |
1093 | + } else { | |
1094 | + workbook = new HSSFWorkbook(); | |
1095 | + } | |
1096 | + | |
1097 | + generateSheet(workbook, data, clazz, isWriteHeader, sheetName); | |
1098 | + | |
1099 | + return workbook; | |
1100 | + } | |
1101 | + | |
1102 | + /** | |
1103 | + * 无模板、基于注解、多sheet数据 | |
1104 | + * | |
1105 | + * @param sheets 待导出sheet数据 | |
1106 | + * @param targetPath 生成的Excel输出全路径 | |
1107 | + * @throws Excel4JException 异常 | |
1108 | + * @throws IOException 异常 | |
1109 | + */ | |
1110 | + public void noTemplateSheet2Excel(List<NoTemplateSheetWrapper> sheets, String targetPath) | |
1111 | + throws Excel4JException, IOException { | |
1112 | + | |
1113 | + try (OutputStream fos = new FileOutputStream(targetPath); | |
1114 | + Workbook workbook = exportExcelNoTemplateHandler(sheets, true)) { | |
1115 | + workbook.write(fos); | |
1116 | + } | |
1117 | + } | |
1118 | + | |
1119 | + /** | |
1120 | + * 无模板、基于注解、多sheet数据 | |
1121 | + * | |
1122 | + * @param sheets 待导出sheet数据 | |
1123 | + * @param isXSSF 导出的Excel是否为Excel2007及以上版本(默认是) | |
1124 | + * @param targetPath 生成的Excel输出全路径 | |
1125 | + * @throws Excel4JException 异常 | |
1126 | + * @throws IOException 异常 | |
1127 | + */ | |
1128 | + public void noTemplateSheet2Excel(List<NoTemplateSheetWrapper> sheets, boolean isXSSF, String targetPath) | |
1129 | + throws Excel4JException, IOException { | |
1130 | + | |
1131 | + try (OutputStream fos = new FileOutputStream(targetPath); | |
1132 | + Workbook workbook = exportExcelNoTemplateHandler(sheets, isXSSF)) { | |
1133 | + workbook.write(fos); | |
1134 | + } | |
1135 | + } | |
1136 | + | |
1137 | + /** | |
1138 | + * 无模板、基于注解、多sheet数据 | |
1139 | + * | |
1140 | + * @param sheets 待导出sheet数据 | |
1141 | + * @param os 生成的Excel输出文件流 | |
1142 | + * @throws Excel4JException 异常 | |
1143 | + * @throws IOException 异常 | |
1144 | + */ | |
1145 | + public void noTemplateSheet2Excel(List<NoTemplateSheetWrapper> sheets, OutputStream os) | |
1146 | + throws Excel4JException, IOException { | |
1147 | + | |
1148 | + try (Workbook workbook = exportExcelNoTemplateHandler(sheets, true)) { | |
1149 | + workbook.write(os); | |
1150 | + } | |
1151 | + } | |
1152 | + | |
1153 | + /** | |
1154 | + * 无模板、基于注解、多sheet数据 | |
1155 | + * | |
1156 | + * @param sheets 待导出sheet数据 | |
1157 | + * @param isXSSF 导出的Excel是否为Excel2007及以上版本(默认是) | |
1158 | + * @param os 生成的Excel输出文件流 | |
1159 | + * @throws Excel4JException 异常 | |
1160 | + * @throws IOException 异常 | |
1161 | + */ | |
1162 | + public void noTemplateSheet2Excel(List<NoTemplateSheetWrapper> sheets, boolean isXSSF, OutputStream os) | |
1163 | + throws Excel4JException, IOException { | |
1164 | + | |
1165 | + try (Workbook workbook = exportExcelNoTemplateHandler(sheets, isXSSF)) { | |
1166 | + workbook.write(os); | |
1167 | + } | |
1168 | + } | |
1169 | + | |
1170 | + // 多sheet数据导出 | |
1171 | + private Workbook exportExcelNoTemplateHandler(List<NoTemplateSheetWrapper> sheetWrappers, boolean isXSSF) | |
1172 | + throws Excel4JException { | |
1173 | + | |
1174 | + Workbook workbook; | |
1175 | + if (isXSSF) { | |
1176 | + workbook = new XSSFWorkbook(); | |
1177 | + } else { | |
1178 | + workbook = new HSSFWorkbook(); | |
1179 | + } | |
1180 | + | |
1181 | + // 导出sheet | |
1182 | + for (NoTemplateSheetWrapper sheet : sheetWrappers) { | |
1183 | + generateSheet(workbook, sheet.getData(), | |
1184 | + sheet.getClazz(), sheet.isWriteHeader(), | |
1185 | + sheet.getSheetName() | |
1186 | + ); | |
1187 | + } | |
1188 | + | |
1189 | + return workbook; | |
1190 | + } | |
1191 | + | |
1192 | + // 生成sheet数据 | |
1193 | + private void generateSheet(Workbook workbook, List<?> data, Class clazz, | |
1194 | + boolean isWriteHeader, String sheetName) | |
1195 | + throws Excel4JException { | |
1196 | + | |
1197 | + Sheet sheet; | |
1198 | + if (null != sheetName && !"".equals(sheetName)) { | |
1199 | + sheet = workbook.createSheet(sheetName); | |
1200 | + } else { | |
1201 | + sheet = workbook.createSheet(); | |
1202 | + } | |
1203 | + Row row = sheet.createRow(0); | |
1204 | + List<ExcelHeader> headers = Utils.getHeaderList(clazz); | |
1205 | + if (isWriteHeader) { | |
1206 | + // 写标题 | |
1207 | + for (int i = 0; i < headers.size(); i++) { | |
1208 | + row.createCell(i).setCellValue(headers.get(i).getTitle()); | |
1209 | + } | |
1210 | + } | |
1211 | + // 写数据 | |
1212 | + Object _data; | |
1213 | + for (int i = 0; i < data.size(); i++) { | |
1214 | + row = sheet.createRow(i + 1); | |
1215 | + _data = data.get(i); | |
1216 | + for (int j = 0; j < headers.size(); j++) { | |
1217 | + row.createCell(j).setCellValue(Utils.getProperty(_data, | |
1218 | + headers.get(j).getFiled(), | |
1219 | + headers.get(j).getWriteConverter())); | |
1220 | + } | |
1221 | + } | |
1222 | + | |
1223 | + } | |
1224 | + | |
1225 | + /*---------------------------------------6.无模板无注解导出----------------------------------------------------*/ | |
1226 | + /* 一. 操作流程 : */ | |
1227 | + /* 1) 写入表头内容(可选) */ | |
1228 | + /* 2) 写入数据内容 */ | |
1229 | + /* 二. 参数说明 */ | |
1230 | + /* *) data => 导出内容List集合 */ | |
1231 | + /* *) header => 表头集合,有则写,无则不写 */ | |
1232 | + /* *) sheetName => Sheet索引名(默认0) */ | |
1233 | + /* *) isXSSF => 是否Excel2007及以上版本 */ | |
1234 | + /* *) targetPath => 导出文件路径 */ | |
1235 | + /* *) os => 导出文件流 */ | |
1236 | + | |
1237 | + /** | |
1238 | + * 无模板、无注解的数据(形如{@code List[?]}、{@code List[List[?]]}、{@code List[Object[]]})导出 | |
1239 | + * | |
1240 | + * @param data 待导出数据 | |
1241 | + * @param header 设置表头信息 | |
1242 | + * @param sheetName 指定导出Excel的sheet名称 | |
1243 | + * @param isXSSF 导出的Excel是否为Excel2007及以上版本(默认是) | |
1244 | + * @param targetPath 生成的Excel输出全路径 | |
1245 | + * @throws IOException 异常 | |
1246 | + * @author Crab2Died | |
1247 | + */ | |
1248 | + public void exportObjects2Excel(List<?> data, List<String> header, String sheetName, | |
1249 | + boolean isXSSF, String targetPath) | |
1250 | + throws IOException { | |
1251 | + | |
1252 | + try (OutputStream fos = new FileOutputStream(targetPath); | |
1253 | + Workbook workbook = exportExcelBySimpleHandler(data, header, sheetName, isXSSF)) { | |
1254 | + workbook.write(fos); | |
1255 | + } | |
1256 | + } | |
1257 | + | |
1258 | + /** | |
1259 | + * 无模板、无注解的数据(形如{@code List[?]}、{@code List[List[?]]}、{@code List[Object[]]})导出 | |
1260 | + * | |
1261 | + * @param data 待导出数据 | |
1262 | + * @param header 设置表头信息 | |
1263 | + * @param sheetName 指定导出Excel的sheet名称 | |
1264 | + * @param isXSSF 导出的Excel是否为Excel2007及以上版本(默认是) | |
1265 | + * @param os 生成的Excel待输出数据流 | |
1266 | + * @throws IOException 异常 | |
1267 | + * @author Crab2Died | |
1268 | + */ | |
1269 | + public void exportObjects2Excel(List<?> data, List<String> header, String sheetName, | |
1270 | + boolean isXSSF, OutputStream os) | |
1271 | + throws IOException { | |
1272 | + | |
1273 | + try (Workbook workbook = exportExcelBySimpleHandler(data, header, sheetName, isXSSF)) { | |
1274 | + workbook.write(os); | |
1275 | + } | |
1276 | + } | |
1277 | + | |
1278 | + /** | |
1279 | + * 无模板、无注解的数据(形如{@code List[?]}、{@code List[List[?]]}、{@code List[Object[]]})导出 | |
1280 | + * | |
1281 | + * @param data 待导出数据 | |
1282 | + * @param header 设置表头信息 | |
1283 | + * @param targetPath 生成的Excel输出全路径 | |
1284 | + * @throws IOException 异常 | |
1285 | + * @author Crab2Died | |
1286 | + */ | |
1287 | + public void exportObjects2Excel(List<?> data, List<String> header, String targetPath) | |
1288 | + throws IOException { | |
1289 | + | |
1290 | + try (OutputStream fos = new FileOutputStream(targetPath); | |
1291 | + Workbook workbook = exportExcelBySimpleHandler(data, header, null, true)) { | |
1292 | + workbook.write(fos); | |
1293 | + } | |
1294 | + } | |
1295 | + | |
1296 | + /** | |
1297 | + * 无模板、无注解的数据(形如{@code List[?]}、{@code List[List[?]]}、{@code List[Object[]]})导出 | |
1298 | + * | |
1299 | + * @param data 待导出数据 | |
1300 | + * @param header 设置表头信息 | |
1301 | + * @param os 生成的Excel待输出数据流 | |
1302 | + * @throws IOException 异常 | |
1303 | + * @author Crab2Died | |
1304 | + */ | |
1305 | + public void exportObjects2Excel(List<?> data, List<String> header, OutputStream os) | |
1306 | + throws IOException { | |
1307 | + | |
1308 | + try (Workbook workbook = exportExcelBySimpleHandler(data, header, null, true)) { | |
1309 | + workbook.write(os); | |
1310 | + } | |
1311 | + } | |
1312 | + | |
1313 | + /** | |
1314 | + * 无模板、无注解的数据(形如{@code List[?]}、{@code List[List[?]]}、{@code List[Object[]]})导出 | |
1315 | + * | |
1316 | + * @param data 待导出数据 | |
1317 | + * @param targetPath 生成的Excel输出全路径 | |
1318 | + * @throws IOException 异常 | |
1319 | + * @author Crab2Died | |
1320 | + */ | |
1321 | + public void exportObjects2Excel(List<?> data, String targetPath) | |
1322 | + throws IOException { | |
1323 | + | |
1324 | + try (OutputStream fos = new FileOutputStream(targetPath); | |
1325 | + Workbook workbook = exportExcelBySimpleHandler(data, null, null, true)) { | |
1326 | + workbook.write(fos); | |
1327 | + } | |
1328 | + } | |
1329 | + | |
1330 | + /** | |
1331 | + * 无模板、无注解的数据(形如{@code List[?]}、{@code List[List[?]]}、{@code List[Object[]]})导出 | |
1332 | + * | |
1333 | + * @param data 待导出数据 | |
1334 | + * @param os 生成的Excel待输出数据流 | |
1335 | + * @throws IOException 异常 | |
1336 | + * @author Crab2Died | |
1337 | + */ | |
1338 | + public void exportObjects2Excel(List<?> data, OutputStream os) | |
1339 | + throws IOException { | |
1340 | + | |
1341 | + try (Workbook workbook = exportExcelBySimpleHandler(data, null, null, true)) { | |
1342 | + workbook.write(os); | |
1343 | + } | |
1344 | + } | |
1345 | + | |
1346 | + private Workbook exportExcelBySimpleHandler(List<?> data, List<String> header, | |
1347 | + String sheetName, boolean isXSSF) { | |
1348 | + | |
1349 | + Workbook workbook; | |
1350 | + if (isXSSF) { | |
1351 | + workbook = new XSSFWorkbook(); | |
1352 | + } else { | |
1353 | + workbook = new HSSFWorkbook(); | |
1354 | + } | |
1355 | + // 生成sheet | |
1356 | + this.generateSheet(workbook, data, header, sheetName); | |
1357 | + | |
1358 | + return workbook; | |
1359 | + } | |
1360 | + | |
1361 | + /** | |
1362 | + * 无模板、无注解、多sheet数据 | |
1363 | + * | |
1364 | + * @param sheets 待导出sheet数据 | |
1365 | + * @param targetPath 生成的Excel输出全路径 | |
1366 | + * @throws IOException 异常 | |
1367 | + */ | |
1368 | + public void simpleSheet2Excel(List<SimpleSheetWrapper> sheets, String targetPath) | |
1369 | + throws IOException { | |
1370 | + | |
1371 | + try (OutputStream fos = new FileOutputStream(targetPath); | |
1372 | + Workbook workbook = exportExcelBySimpleHandler(sheets, true)) { | |
1373 | + workbook.write(fos); | |
1374 | + } | |
1375 | + } | |
1376 | + | |
1377 | + /** | |
1378 | + * 无模板、无注解、多sheet数据 | |
1379 | + * | |
1380 | + * @param sheets 待导出sheet数据 | |
1381 | + * @param isXSSF 导出的Excel是否为Excel2007及以上版本(默认是) | |
1382 | + * @param targetPath 生成的Excel输出全路径 | |
1383 | + * @throws IOException 异常 | |
1384 | + */ | |
1385 | + public void simpleSheet2Excel(List<SimpleSheetWrapper> sheets, boolean isXSSF, String targetPath) | |
1386 | + throws IOException { | |
1387 | + | |
1388 | + try (OutputStream fos = new FileOutputStream(targetPath); | |
1389 | + Workbook workbook = exportExcelBySimpleHandler(sheets, isXSSF)) { | |
1390 | + workbook.write(fos); | |
1391 | + } | |
1392 | + } | |
1393 | + | |
1394 | + /** | |
1395 | + * 无模板、无注解、多sheet数据 | |
1396 | + * | |
1397 | + * @param sheets 待导出sheet数据 | |
1398 | + * @param os 生成的Excel待输出数据流 | |
1399 | + * @throws IOException 异常 | |
1400 | + */ | |
1401 | + public void simpleSheet2Excel(List<SimpleSheetWrapper> sheets, OutputStream os) | |
1402 | + throws IOException { | |
1403 | + | |
1404 | + try (Workbook workbook = exportExcelBySimpleHandler(sheets, true)) { | |
1405 | + workbook.write(os); | |
1406 | + } | |
1407 | + } | |
1408 | + | |
1409 | + /** | |
1410 | + * 无模板、无注解、多sheet数据 | |
1411 | + * | |
1412 | + * @param sheets 待导出sheet数据 | |
1413 | + * @param isXSSF 导出的Excel是否为Excel2007及以上版本(默认是) | |
1414 | + * @param os 生成的Excel待输出数据流 | |
1415 | + * @throws IOException 异常 | |
1416 | + */ | |
1417 | + public void simpleSheet2Excel(List<SimpleSheetWrapper> sheets, boolean isXSSF, OutputStream os) | |
1418 | + throws IOException { | |
1419 | + | |
1420 | + try (Workbook workbook = exportExcelBySimpleHandler(sheets, isXSSF)) { | |
1421 | + workbook.write(os); | |
1422 | + } | |
1423 | + } | |
1424 | + | |
1425 | + private Workbook exportExcelBySimpleHandler(List<SimpleSheetWrapper> sheets, boolean isXSSF) { | |
1426 | + | |
1427 | + Workbook workbook; | |
1428 | + if (isXSSF) { | |
1429 | + workbook = new XSSFWorkbook(); | |
1430 | + } else { | |
1431 | + workbook = new HSSFWorkbook(); | |
1432 | + } | |
1433 | + // 生成多sheet | |
1434 | + for (SimpleSheetWrapper sheet : sheets) { | |
1435 | + this.generateSheet(workbook, sheet.getData(), sheet.getHeader(), sheet.getSheetName()); | |
1436 | + } | |
1437 | + | |
1438 | + return workbook; | |
1439 | + } | |
1440 | + | |
1441 | + // 生成sheet数据内容 | |
1442 | + private void generateSheet(Workbook workbook, List<?> data, List<String> header, String sheetName) { | |
1443 | + | |
1444 | + Sheet sheet; | |
1445 | + if (null != sheetName && !"".equals(sheetName)) { | |
1446 | + sheet = workbook.createSheet(sheetName); | |
1447 | + } else { | |
1448 | + sheet = workbook.createSheet(); | |
1449 | + } | |
1450 | + | |
1451 | + int rowIndex = 0; | |
1452 | + if (null != header && header.size() > 0) { | |
1453 | + // 写标题 | |
1454 | + Row row = sheet.createRow(rowIndex++); | |
1455 | + for (int i = 0; i < header.size(); i++) { | |
1456 | + row.createCell(i, CellType.STRING).setCellValue(header.get(i)); | |
1457 | + } | |
1458 | + } | |
1459 | + for (Object object : data) { | |
1460 | + Row row = sheet.createRow(rowIndex++); | |
1461 | + if (object.getClass().isArray()) { | |
1462 | + for (int j = 0; j < Array.getLength(object); j++) { | |
1463 | + row.createCell(j, CellType.STRING).setCellValue(Array.get(object, j).toString()); | |
1464 | + } | |
1465 | + } else if (object instanceof Collection) { | |
1466 | + Collection<?> items = (Collection<?>) object; | |
1467 | + int j = 0; | |
1468 | + for (Object item : items) { | |
1469 | + row.createCell(j++, CellType.STRING).setCellValue(item.toString()); | |
1470 | + } | |
1471 | + } else { | |
1472 | + row.createCell(0, CellType.STRING).setCellValue(object.toString()); | |
1473 | + } | |
1474 | + } | |
1475 | + } | |
1476 | + | |
1477 | + /*---------------------------------------7.基于注解的CSV读取--------------------------------------------------*/ | |
1478 | + /* 一. 操作流程 : */ | |
1479 | + /* 1) 读取表头信息,与给出的Class类注解匹配 */ | |
1480 | + /* 2) 读取表头下面的数据内容, 按行读取, 并映射至java对象 */ | |
1481 | + /* 二. 参数说明 */ | |
1482 | + /* *) path => 待读取文件路径 */ | |
1483 | + /* *) is => 待读取文件流 */ | |
1484 | + /* *) clazz => 映射对象 */ | |
1485 | + | |
1486 | + /** | |
1487 | + * 基于注解读取CSV文件 | |
1488 | + * | |
1489 | + * @param path 待读取文件路径 | |
1490 | + * @param clazz 待绑定的类(绑定属性注解{@link }) | |
1491 | + * @return 返回转换为设置绑定的java对象集合 | |
1492 | + * @throws Excel4jReadException exception | |
1493 | + */ | |
1494 | + public <T> List<T> readCSV2Objects(String path, Class<T> clazz) { | |
1495 | + | |
1496 | + try (InputStream is = new FileInputStream(new File(path))) { | |
1497 | + return readCSVByMapHandler(is, clazz); | |
1498 | + } catch (IOException | Excel4JException e) { | |
1499 | + throw new Excel4jReadException("read [" + path + "] CSV Error: ", e); | |
1500 | + } | |
1501 | + } | |
1502 | + | |
1503 | + /** | |
1504 | + * 基于注解读取CSV文件 | |
1505 | + * | |
1506 | + * @param is 待读取文件输入流 | |
1507 | + * @param clazz 待绑定的类(绑定属性注解{@link }) | |
1508 | + * @return 返回转换为设置绑定的java对象集合 | |
1509 | + * @throws Excel4jReadException exception | |
1510 | + */ | |
1511 | + public <T> List<T> readCSV2Objects(InputStream is, Class<T> clazz) { | |
1512 | + | |
1513 | + try { | |
1514 | + return readCSVByMapHandler(is, clazz); | |
1515 | + } catch (Excel4JException | IOException e) { | |
1516 | + throw new Excel4jReadException("read CSV Error: ", e); | |
1517 | + } | |
1518 | + } | |
1519 | + | |
1520 | + // 读取csv | |
1521 | + private <T> List<T> readCSVByMapHandler(InputStream is, Class<T> clazz) | |
1522 | + throws IOException, Excel4JException { | |
1523 | + | |
1524 | + List<T> records = new ArrayList<>(); | |
1525 | + | |
1526 | + List<ExcelHeader> headers = Utils.getHeaderList(clazz); | |
1527 | + if (null == headers || headers.size() <= 0) { | |
1528 | + throw new Excel4jReadException("[" + clazz + "] must configuration @ExcelFiled"); | |
1529 | + } | |
1530 | + String[] csvHeaders = new String[headers.size()]; | |
1531 | + for (int i = 0; i < headers.size(); i++) { | |
1532 | + csvHeaders[i] = headers.get(i).getTitle(); | |
1533 | + } | |
1534 | + CSVFormat format = CSVFormat.EXCEL.withHeader(csvHeaders).withSkipHeaderRecord(true); | |
1535 | + try (Reader read = new InputStreamReader(is, StandardCharsets.UTF_8); | |
1536 | + CSVParser parser = new CSVParser(read, format)) { | |
1537 | + for (CSVRecord _parser : parser) { | |
1538 | + T obj; | |
1539 | + try { | |
1540 | + obj = clazz.newInstance(); | |
1541 | + } catch (InstantiationException | IllegalAccessException e) { | |
1542 | + throw new Excel4jReadException(e); | |
1543 | + } | |
1544 | + for (ExcelHeader header : headers) { | |
1545 | + String value = _parser.get(header.getTitle()); | |
1546 | + Object objectVal; | |
1547 | + String filed = header.getFiled(); | |
1548 | + // 读取转换器 | |
1549 | + if (null != header.getReadConverter() && | |
1550 | + header.getReadConverter().getClass() != DefaultConvertible.class) { | |
1551 | + objectVal = header.getReadConverter().execRead(value); | |
1552 | + } else { | |
1553 | + // 默认转换 | |
1554 | + objectVal = Utils.str2TargetClass(value, header.getFiledClazz()); | |
1555 | + } | |
1556 | + Utils.copyProperty(obj, filed, objectVal); | |
1557 | + } | |
1558 | + records.add(obj); | |
1559 | + } | |
1560 | + } | |
1561 | + return records; | |
1562 | + } | |
1563 | + | |
1564 | + /*---------------------------------------8.基于注解的CSV导出--------------------------------------------------*/ | |
1565 | + /* 一. 操作流程 : */ | |
1566 | + /* 1) 写入表头内容(可选) */ | |
1567 | + /* 2) 写入数据内容 */ | |
1568 | + /* 二. 参数说明 */ | |
1569 | + /* *) data => 导出内容List集合 */ | |
1570 | + /* *) isWriteHeader => 是否写表头 */ | |
1571 | + /* *) path => 导出文件路径 */ | |
1572 | + /* *) os => 导出文件流 */ | |
1573 | + /* *) clazz => 映射对象 */ | |
1574 | + | |
1575 | + /** | |
1576 | + * 基于注解导出CSV文件 | |
1577 | + * | |
1578 | + * @param data 待导出 | |
1579 | + * @param clazz {@link }映射对象Class | |
1580 | + * @param path 导出文件路径 | |
1581 | + * @throws Excel4JException exception | |
1582 | + */ | |
1583 | + public void exportObjects2CSV(List<?> data, Class clazz, String path) | |
1584 | + throws Excel4JException { | |
1585 | + | |
1586 | + try { | |
1587 | + Writer writer = new FileWriter(path); | |
1588 | + exportCSVByMapHandler(data, clazz, true, writer); | |
1589 | + } catch (Excel4JException | IOException e) { | |
1590 | + throw new Excel4JException(e); | |
1591 | + } | |
1592 | + } | |
1593 | + | |
1594 | + /** | |
1595 | + * 基于注解导出CSV文件流 | |
1596 | + * | |
1597 | + * @param data 待导出 | |
1598 | + * @param clazz {@link }映射对象Class | |
1599 | + * @param os 输出流 | |
1600 | + * @throws Excel4JException exception | |
1601 | + */ | |
1602 | + public void exportObjects2CSV(List<?> data, Class clazz, OutputStream os) | |
1603 | + throws Excel4JException { | |
1604 | + | |
1605 | + try { | |
1606 | + Writer writer = new OutputStreamWriter(os); | |
1607 | + exportCSVByMapHandler(data, clazz, true, writer); | |
1608 | + } catch (Excel4JException | IOException e) { | |
1609 | + throw new Excel4JException(e); | |
1610 | + } | |
1611 | + } | |
1612 | + | |
1613 | + /** | |
1614 | + * 基于注解导出CSV文件 | |
1615 | + * | |
1616 | + * @param data 待导出 | |
1617 | + * @param clazz {@link }映射对象Class | |
1618 | + * @param isWriteHeader 是否写入文件 | |
1619 | + * @param path 导出文件路径 | |
1620 | + * @throws Excel4JException exception | |
1621 | + */ | |
1622 | + public void exportObjects2CSV(List<?> data, Class clazz, boolean isWriteHeader, String path) | |
1623 | + throws Excel4JException { | |
1624 | + | |
1625 | + try { | |
1626 | + Writer writer = new FileWriter(path); | |
1627 | + exportCSVByMapHandler(data, clazz, isWriteHeader, writer); | |
1628 | + } catch (Excel4JException | IOException e) { | |
1629 | + throw new Excel4JException(e); | |
1630 | + } | |
1631 | + } | |
1632 | + | |
1633 | + /** | |
1634 | + * 基于注解导出CSV文件流 | |
1635 | + * | |
1636 | + * @param data 待导出 | |
1637 | + * @param clazz {@link }映射对象Class | |
1638 | + * @param isWriteHeader 是否写入文件 | |
1639 | + * @param os 输出流 | |
1640 | + * @throws Excel4JException exception | |
1641 | + */ | |
1642 | + public void exportObjects2CSV(List<?> data, Class clazz, boolean isWriteHeader, OutputStream os) | |
1643 | + throws Excel4JException { | |
1644 | + | |
1645 | + try { | |
1646 | + Writer writer = new OutputStreamWriter(os); | |
1647 | + exportCSVByMapHandler(data, clazz, isWriteHeader, writer); | |
1648 | + } catch (Excel4JException | IOException e) { | |
1649 | + throw new Excel4JException(e); | |
1650 | + } | |
1651 | + } | |
1652 | + | |
1653 | + private static final byte[] UTF_8_DOM = {(byte) 0xEF, (byte) 0xBB, (byte) 0xBF}; | |
1654 | + | |
1655 | + // 生成CSV | |
1656 | + private void exportCSVByMapHandler(List<?> data, Class clazz, boolean isWriteHeader, Appendable appendable) | |
1657 | + throws Excel4JException, IOException { | |
1658 | + | |
1659 | + List<ExcelHeader> headers = Utils.getHeaderList(clazz); | |
1660 | + appendable.append(new String(UTF_8_DOM, StandardCharsets.UTF_8)); | |
1661 | + | |
1662 | + try (CSVPrinter printer = new CSVPrinter(appendable, CSVFormat.EXCEL)) { | |
1663 | + | |
1664 | + if (isWriteHeader) { | |
1665 | + for (ExcelHeader header : headers) { | |
1666 | + printer.print(header.getTitle()); | |
1667 | + } | |
1668 | + printer.println(); | |
1669 | + } | |
1670 | + // 写数据 | |
1671 | + for (Object _data : data) { | |
1672 | + for (ExcelHeader header : headers) { | |
1673 | + printer.print( | |
1674 | + Utils.getProperty(_data, header.getFiled(), header.getWriteConverter()) | |
1675 | + ); | |
1676 | + } | |
1677 | + printer.println(); | |
1678 | + } | |
1679 | + printer.flush(); | |
1680 | + } | |
1681 | + } | |
1682 | + | |
1683 | +} | ... | ... |
src/main/java/com/order/erp/common/excel4j/ExcelValidator.java
0 → 100644
1 | +package com.order.erp.common.excel4j; | |
2 | + | |
3 | +import com.order.erp.common.constant.Constant; | |
4 | +import com.order.erp.common.exception.BusinessException; | |
5 | +import com.order.erp.common.utils.StringUtils; | |
6 | +import lombok.extern.slf4j.Slf4j; | |
7 | + | |
8 | +import javax.validation.ConstraintViolation; | |
9 | +import javax.validation.Validation; | |
10 | +import javax.validation.Validator; | |
11 | +import javax.validation.groups.Default; | |
12 | +import java.util.Set; | |
13 | + | |
14 | +/** | |
15 | + * @author fanzhenyu | |
16 | + * @date 2023-02-23 | |
17 | + */ | |
18 | +@Slf4j | |
19 | +public class ExcelValidator { | |
20 | + | |
21 | + | |
22 | + private static Validator validator = Validation.buildDefaultValidatorFactory().getValidator(); | |
23 | + | |
24 | + /** | |
25 | + * 校验遇到第一个不合法的字段直接返回不合法字段,后续字段不再校验 | |
26 | + * @param <T> | |
27 | + * @return | |
28 | + */ | |
29 | + public static <T> void validateEntity(T obj) { | |
30 | + Set<ConstraintViolation<T>> set = validator.validate(obj, Default.class); | |
31 | + String err = collectError(set); | |
32 | + if (StringUtils.isNotBlank(err)){ | |
33 | + throw new BusinessException(com.canrd.shop.common.constant.ServerResultCode.ILLEGAL_ARGUMENT.getErrorCode(),err); | |
34 | + } | |
35 | + } | |
36 | + | |
37 | + private static <T> String collectError(Set<ConstraintViolation<T>> set) { | |
38 | + StringBuilder result = new StringBuilder(); | |
39 | + if (set != null && !set.isEmpty()) { | |
40 | + for (ConstraintViolation<T> cv : set) { | |
41 | + result.append(cv.getMessage()); | |
42 | + result.append(Constant.SEMICOLON_CHARACTER); | |
43 | + } | |
44 | + } | |
45 | + return result.toString(); | |
46 | + } | |
47 | + | |
48 | + | |
49 | + | |
50 | +} | ... | ... |
src/main/java/com/order/erp/common/excel4j/annotation/ExcelField.java
0 → 100644
1 | +package com.order.erp.common.excel4j.annotation; | |
2 | + | |
3 | + | |
4 | +import com.order.erp.common.excel4j.converter.DefaultConvertible; | |
5 | +import com.order.erp.common.excel4j.converter.ReadConvertible; | |
6 | +import com.order.erp.common.excel4j.converter.WriteConvertible; | |
7 | + | |
8 | +import java.lang.annotation.ElementType; | |
9 | +import java.lang.annotation.Retention; | |
10 | +import java.lang.annotation.RetentionPolicy; | |
11 | +import java.lang.annotation.Target; | |
12 | + | |
13 | +/** | |
14 | + * 功能说明: 用来在对象的属性上加入的annotation,通过该annotation说明某个属性所对应的标题 | |
15 | + */ | |
16 | +@Retention(RetentionPolicy.RUNTIME) | |
17 | +@Target(ElementType.FIELD) | |
18 | +public @interface ExcelField { | |
19 | + | |
20 | + /** | |
21 | + * 属性的标题名称 | |
22 | + * | |
23 | + * @return 表头名 | |
24 | + */ | |
25 | + String title(); | |
26 | + | |
27 | + /** | |
28 | + * 写数据转换器 | |
29 | + * | |
30 | + * @return 写入Excel数据转换器 | |
31 | + * @see WriteConvertible | |
32 | + */ | |
33 | + Class<? extends WriteConvertible> writeConverter() | |
34 | + default DefaultConvertible.class; | |
35 | + | |
36 | + /** | |
37 | + * 读数据转换器 | |
38 | + * | |
39 | + * @return 读取Excel数据转换器 | |
40 | + * @see ReadConvertible | |
41 | + */ | |
42 | + Class<? extends ReadConvertible> readConverter() | |
43 | + default DefaultConvertible.class; | |
44 | + | |
45 | + /** | |
46 | + * 在excel的顺序 | |
47 | + * | |
48 | + * @return 列表顺序 | |
49 | + */ | |
50 | + int order() default Integer.MAX_VALUE; | |
51 | +} | ... | ... |
src/main/java/com/order/erp/common/excel4j/converter/DefaultConvertible.java
0 → 100644
1 | +package com.order.erp.common.excel4j.converter; | |
2 | + | |
3 | +/** | |
4 | + * 抽象默认转换器, 实现了{@link WriteConvertible} 与 {@link ReadConvertible}接口 | |
5 | + */ | |
6 | +public class DefaultConvertible implements WriteConvertible, ReadConvertible { | |
7 | + | |
8 | + @Override | |
9 | + public Object execRead(String object) { | |
10 | + throw new UnsupportedOperationException(); | |
11 | + } | |
12 | + | |
13 | + @Override | |
14 | + public Object execWrite(Object object) { | |
15 | + throw new UnsupportedOperationException(); | |
16 | + } | |
17 | +} | ... | ... |
src/main/java/com/order/erp/common/excel4j/converter/ReadConvertible.java
0 → 100644
src/main/java/com/order/erp/common/excel4j/converter/WriteConvertible.java
0 → 100644
src/main/java/com/order/erp/common/excel4j/exceptions/Excel4JException.java
0 → 100644
1 | +package com.order.erp.common.excel4j.exceptions; | |
2 | + | |
3 | +public class Excel4JException extends Exception { | |
4 | + | |
5 | + public Excel4JException() { | |
6 | + } | |
7 | + | |
8 | + public Excel4JException(String message) { | |
9 | + super(message); | |
10 | + } | |
11 | + | |
12 | + public Excel4JException(String message, Throwable cause) { | |
13 | + super(message, cause); | |
14 | + } | |
15 | + | |
16 | + public Excel4JException(Throwable cause) { | |
17 | + super(cause); | |
18 | + } | |
19 | +} | ... | ... |
src/main/java/com/order/erp/common/excel4j/exceptions/Excel4jReadException.java
0 → 100644
1 | +package com.order.erp.common.excel4j.exceptions; | |
2 | + | |
3 | +public class Excel4jReadException extends RuntimeException { | |
4 | + | |
5 | + private static final long serialVersionUID = 8735084330744657672L; | |
6 | + | |
7 | + public Excel4jReadException() { | |
8 | + super(); | |
9 | + } | |
10 | + | |
11 | + public Excel4jReadException(Throwable cause) { | |
12 | + super(cause); | |
13 | + } | |
14 | + | |
15 | + public Excel4jReadException(String message) { | |
16 | + super(message); | |
17 | + } | |
18 | + | |
19 | + public Excel4jReadException(String message, Throwable cause) { | |
20 | + super(message, cause); | |
21 | + } | |
22 | +} | ... | ... |
src/main/java/com/order/erp/common/excel4j/exceptions/IllegalGroupIndexException.java
0 → 100644
1 | +package com.order.erp.common.excel4j.exceptions; | |
2 | + | |
3 | +public class IllegalGroupIndexException extends RuntimeException { | |
4 | + | |
5 | + private static final long serialVersionUID = 7725478743860387475L; | |
6 | + | |
7 | + public IllegalGroupIndexException(String message) { | |
8 | + super(message); | |
9 | + } | |
10 | +} | ... | ... |
src/main/java/com/order/erp/common/excel4j/exceptions/TimeMatchFormatException.java
0 → 100644
1 | +package com.order.erp.common.excel4j.exceptions; | |
2 | + | |
3 | +public class TimeMatchFormatException extends RuntimeException { | |
4 | + | |
5 | + private static final long serialVersionUID = 206910143412957809L; | |
6 | + | |
7 | + public TimeMatchFormatException() { | |
8 | + } | |
9 | + | |
10 | + public TimeMatchFormatException(String message) { | |
11 | + super(message); | |
12 | + } | |
13 | + | |
14 | + public TimeMatchFormatException(String message, Throwable cause) { | |
15 | + super(message, cause); | |
16 | + } | |
17 | +} | ... | ... |
src/main/java/com/order/erp/common/excel4j/handler/ExcelHeader.java
0 → 100644
1 | +package com.order.erp.common.excel4j.handler; | |
2 | + | |
3 | + | |
4 | +import com.order.erp.common.excel4j.converter.ReadConvertible; | |
5 | +import com.order.erp.common.excel4j.converter.WriteConvertible; | |
6 | + | |
7 | +/** | |
8 | + * 功能说明: 用来存储Excel标题的对象,通过该对象可以获取标题和方法的对应关系 | |
9 | + */ | |
10 | +public class ExcelHeader implements Comparable<ExcelHeader> { | |
11 | + | |
12 | + /** | |
13 | + * excel的标题名称 | |
14 | + */ | |
15 | + private String title; | |
16 | + | |
17 | + /** | |
18 | + * 每一个标题的顺序 | |
19 | + */ | |
20 | + private int order; | |
21 | + | |
22 | + /** | |
23 | + * 写数据转换器 | |
24 | + */ | |
25 | + private WriteConvertible writeConverter; | |
26 | + | |
27 | + /** | |
28 | + * 读数据转换器 | |
29 | + */ | |
30 | + private ReadConvertible readConverter; | |
31 | + | |
32 | + /** | |
33 | + * 注解域 | |
34 | + */ | |
35 | + private String filed; | |
36 | + | |
37 | + /** | |
38 | + * 属性类型 | |
39 | + */ | |
40 | + private Class<?> filedClazz; | |
41 | + | |
42 | + | |
43 | + public String getTitle() { | |
44 | + return title; | |
45 | + } | |
46 | + | |
47 | + public void setTitle(String title) { | |
48 | + this.title = title; | |
49 | + } | |
50 | + | |
51 | + public int getOrder() { | |
52 | + return order; | |
53 | + } | |
54 | + | |
55 | + public void setOrder(int order) { | |
56 | + this.order = order; | |
57 | + } | |
58 | + | |
59 | + public WriteConvertible getWriteConverter() { | |
60 | + return writeConverter; | |
61 | + } | |
62 | + | |
63 | + public void setWriteConverter(WriteConvertible writeConverter) { | |
64 | + this.writeConverter = writeConverter; | |
65 | + } | |
66 | + | |
67 | + public ReadConvertible getReadConverter() { | |
68 | + return readConverter; | |
69 | + } | |
70 | + | |
71 | + public void setReadConverter(ReadConvertible readConverter) { | |
72 | + this.readConverter = readConverter; | |
73 | + } | |
74 | + | |
75 | + public String getFiled() { | |
76 | + return filed; | |
77 | + } | |
78 | + | |
79 | + public void setFiled(String filed) { | |
80 | + this.filed = filed; | |
81 | + } | |
82 | + | |
83 | + public Class<?> getFiledClazz() { | |
84 | + return filedClazz; | |
85 | + } | |
86 | + | |
87 | + public void setFiledClazz(Class<?> filedClazz) { | |
88 | + this.filedClazz = filedClazz; | |
89 | + } | |
90 | + | |
91 | + @Override | |
92 | + public int compareTo(ExcelHeader o) { | |
93 | + return order - o.order; | |
94 | + } | |
95 | + | |
96 | + public ExcelHeader() { | |
97 | + super(); | |
98 | + } | |
99 | + | |
100 | + public ExcelHeader(String title, int order, WriteConvertible writeConverter, | |
101 | + ReadConvertible readConverter, String filed, Class<?> filedClazz) { | |
102 | + super(); | |
103 | + this.title = title; | |
104 | + this.order = order; | |
105 | + this.writeConverter = writeConverter; | |
106 | + this.readConverter = readConverter; | |
107 | + this.filed = filed; | |
108 | + this.filedClazz = filedClazz; | |
109 | + } | |
110 | + | |
111 | + | |
112 | +} | ... | ... |
src/main/java/com/order/erp/common/excel4j/handler/HandlerConstant.java
0 → 100644
1 | +package com.order.erp.common.excel4j.handler; | |
2 | + | |
3 | + | |
4 | +/** | |
5 | + * <p>Excel模板自定义属性,不区分大小写</p> | |
6 | + */ | |
7 | +final class HandlerConstant { | |
8 | + | |
9 | + // 数据插入起始坐标点 | |
10 | + static final String DATA_INIT_INDEX = "$data_index"; | |
11 | + | |
12 | + // 默认样式 | |
13 | + static final String DEFAULT_STYLE = "$default_style"; | |
14 | + | |
15 | + // 当前标记行样式 | |
16 | + static final String APPOINT_LINE_STYLE = "$appoint_line_style"; | |
17 | + | |
18 | + // 单数行样式 | |
19 | + static final String SINGLE_LINE_STYLE = "$single_line_style"; | |
20 | + | |
21 | + // 双数行样式 | |
22 | + static final String DOUBLE_LINE_STYLE = "$double_line_style"; | |
23 | + | |
24 | + // 序号列坐标点 | |
25 | + static final String SERIAL_NUMBER = "$serial_number"; | |
26 | + | |
27 | +} | ... | ... |
src/main/java/com/order/erp/common/excel4j/handler/SheetTemplate.java
0 → 100644
1 | +package com.order.erp.common.excel4j.handler; | |
2 | + | |
3 | +import com.order.erp.common.excel4j.exceptions.Excel4JException; | |
4 | +import org.apache.poi.ss.usermodel.CellStyle; | |
5 | +import org.apache.poi.ss.usermodel.Row; | |
6 | +import org.apache.poi.ss.usermodel.Sheet; | |
7 | +import org.apache.poi.ss.usermodel.Workbook; | |
8 | + | |
9 | +import java.io.Closeable; | |
10 | +import java.io.FileOutputStream; | |
11 | +import java.io.IOException; | |
12 | +import java.io.OutputStream; | |
13 | +import java.util.HashMap; | |
14 | +import java.util.Map; | |
15 | + | |
16 | +public class SheetTemplate implements Closeable { | |
17 | + | |
18 | + /** | |
19 | + * 当前工作簿 | |
20 | + */ | |
21 | + Workbook workbook; | |
22 | + /** | |
23 | + * 当前工作sheet表 | |
24 | + */ | |
25 | + Sheet sheet; | |
26 | + /** | |
27 | + * 当前表编号 | |
28 | + */ | |
29 | + int sheetIndex; | |
30 | + /** | |
31 | + * 当前行 | |
32 | + */ | |
33 | + Row currentRow; | |
34 | + /** | |
35 | + * 当前列数 | |
36 | + */ | |
37 | + int currentColumnIndex; | |
38 | + /** | |
39 | + * 当前行数 | |
40 | + */ | |
41 | + int currentRowIndex; | |
42 | + /** | |
43 | + * 默认样式 | |
44 | + */ | |
45 | + CellStyle defaultStyle; | |
46 | + /** | |
47 | + * 指定行样式 | |
48 | + */ | |
49 | + Map<Integer, CellStyle> appointLineStyle = new HashMap<>(); | |
50 | + /** | |
51 | + * 分类样式模板 | |
52 | + */ | |
53 | + Map<String, CellStyle> classifyStyle = new HashMap<>(); | |
54 | + /** | |
55 | + * 单数行样式 | |
56 | + */ | |
57 | + CellStyle singleLineStyle; | |
58 | + /** | |
59 | + * 双数行样式 | |
60 | + */ | |
61 | + CellStyle doubleLineStyle; | |
62 | + /** | |
63 | + * 数据的初始化列数 | |
64 | + */ | |
65 | + int initColumnIndex; | |
66 | + /** | |
67 | + * 数据的初始化行数 | |
68 | + */ | |
69 | + int initRowIndex; | |
70 | + | |
71 | + /** | |
72 | + * 最后一行的数据 | |
73 | + */ | |
74 | + int lastRowIndex; | |
75 | + /** | |
76 | + * 默认行高 | |
77 | + */ | |
78 | + float rowHeight; | |
79 | + /** | |
80 | + * 序号坐标点 | |
81 | + */ | |
82 | + int serialNumberColumnIndex = -1; | |
83 | + /** | |
84 | + * 当前序号 | |
85 | + */ | |
86 | + int serialNumber; | |
87 | + | |
88 | + /*-----------------------------------写出数据开始-----------------------------------*/ | |
89 | + | |
90 | + /** | |
91 | + * 将文件写到相应的路径下 | |
92 | + * | |
93 | + * @param filePath 输出文件路径 | |
94 | + */ | |
95 | + public void write2File(String filePath) throws Excel4JException { | |
96 | + | |
97 | + try (FileOutputStream fos = new FileOutputStream(filePath)) { | |
98 | + this.workbook.write(fos); | |
99 | + } catch (IOException e) { | |
100 | + throw new Excel4JException(e); | |
101 | + } | |
102 | + } | |
103 | + | |
104 | + /** | |
105 | + * 将文件写到某个输出流中 | |
106 | + * | |
107 | + * @param os 输出流 | |
108 | + */ | |
109 | + public void write2Stream(OutputStream os) throws Excel4JException { | |
110 | + | |
111 | + try { | |
112 | + this.workbook.write(os); | |
113 | + } catch (IOException e) { | |
114 | + throw new Excel4JException(e); | |
115 | + } | |
116 | + } | |
117 | + | |
118 | + /*-----------------------------------写出数据结束-----------------------------------*/ | |
119 | + | |
120 | + @Override | |
121 | + public void close() throws IOException { | |
122 | + if (null != this.workbook) { | |
123 | + this.workbook.close(); | |
124 | + } | |
125 | + } | |
126 | + | |
127 | +} | ... | ... |
src/main/java/com/order/erp/common/excel4j/handler/SheetTemplateHandler.java
0 → 100644
1 | +package com.order.erp.common.excel4j.handler; | |
2 | + | |
3 | +import com.order.erp.common.excel4j.exceptions.Excel4JException; | |
4 | +import org.apache.poi.openxml4j.exceptions.InvalidFormatException; | |
5 | +import org.apache.poi.ss.usermodel.*; | |
6 | + | |
7 | +import java.io.File; | |
8 | +import java.io.FileInputStream; | |
9 | +import java.io.IOException; | |
10 | +import java.io.InputStream; | |
11 | +import java.util.Calendar; | |
12 | +import java.util.Date; | |
13 | +import java.util.Map; | |
14 | + | |
15 | +public class SheetTemplateHandler { | |
16 | + | |
17 | + // 构建SheetTemplate | |
18 | + public static SheetTemplate sheetTemplateBuilder(String templatePath) | |
19 | + throws Excel4JException { | |
20 | + SheetTemplate sheetTemplate = new SheetTemplate(); | |
21 | + try { | |
22 | + // 读取模板文件 | |
23 | + sheetTemplate.workbook = WorkbookFactory.create(new FileInputStream(new File(templatePath))); | |
24 | + } catch (Exception e) { | |
25 | + // 读取模板相对文件 | |
26 | + try { | |
27 | + sheetTemplate.workbook = WorkbookFactory.create( | |
28 | + SheetTemplateHandler.class.getResourceAsStream(templatePath) | |
29 | + ); | |
30 | + } catch (IOException | InvalidFormatException e1) { | |
31 | + throw new Excel4JException(e1); | |
32 | + } | |
33 | + } | |
34 | + return sheetTemplate; | |
35 | + } | |
36 | + | |
37 | + public static SheetTemplate sheetTemplateBuilder(InputStream is) | |
38 | + throws Excel4JException { | |
39 | + SheetTemplate sheetTemplate = new SheetTemplate(); | |
40 | + | |
41 | + // 读取模板文件 | |
42 | + try { | |
43 | + sheetTemplate.workbook = WorkbookFactory.create(is); | |
44 | + } catch (IOException | InvalidFormatException e) { | |
45 | + throw new Excel4JException(e); | |
46 | + } | |
47 | + return sheetTemplate; | |
48 | + } | |
49 | + | |
50 | + /*-----------------------------------初始化模板开始-----------------------------------*/ | |
51 | + | |
52 | + public static void loadTemplate(SheetTemplate template, int sheetIndex) { | |
53 | + | |
54 | + if (sheetIndex < 0) { | |
55 | + sheetIndex = 0; | |
56 | + } | |
57 | + template.sheetIndex = sheetIndex; | |
58 | + template.sheet = template.workbook.getSheetAt(sheetIndex); | |
59 | + initModuleConfig(template); | |
60 | + template.currentRowIndex = template.initRowIndex; | |
61 | + template.currentColumnIndex = template.initColumnIndex; | |
62 | + template.lastRowIndex = template.sheet.getLastRowNum(); | |
63 | + } | |
64 | + | |
65 | + /** | |
66 | + * 初始化数据信息 | |
67 | + */ | |
68 | + private static void initModuleConfig(SheetTemplate template) { | |
69 | + | |
70 | + for (Row row : template.sheet) { | |
71 | + for (Cell c : row) { | |
72 | + if (c.getCellTypeEnum() != CellType.STRING) { | |
73 | + continue; | |
74 | + } | |
75 | + String str = c.getStringCellValue().trim().toLowerCase(); | |
76 | + // 寻找序号列 | |
77 | + if (HandlerConstant.SERIAL_NUMBER.equals(str)) { | |
78 | + template.serialNumberColumnIndex = c.getColumnIndex(); | |
79 | + } | |
80 | + // 寻找数据列 | |
81 | + if (HandlerConstant.DATA_INIT_INDEX.equals(str)) { | |
82 | + template.initColumnIndex = c.getColumnIndex(); | |
83 | + template.initRowIndex = row.getRowNum(); | |
84 | + template.rowHeight = row.getHeightInPoints(); | |
85 | + } | |
86 | + // 初始化自定义模板样式 | |
87 | + initStyles(template, c, str); | |
88 | + } | |
89 | + } | |
90 | + } | |
91 | + | |
92 | + /** | |
93 | + * 初始化样式信息 | |
94 | + */ | |
95 | + private static void initStyles(SheetTemplate template, Cell cell, String moduleContext) { | |
96 | + if (null == moduleContext || "".equals(moduleContext)) { | |
97 | + return; | |
98 | + } | |
99 | + if (!moduleContext.startsWith("&")) { | |
100 | + moduleContext = moduleContext.toLowerCase(); | |
101 | + } | |
102 | + | |
103 | + if (HandlerConstant.DEFAULT_STYLE.equals(moduleContext)) { | |
104 | + template.defaultStyle = cell.getCellStyle(); | |
105 | + clearCell(cell); | |
106 | + } | |
107 | + if (moduleContext.startsWith("&") && moduleContext.length() > 1) { | |
108 | + template.classifyStyle.put(moduleContext.substring(1), cell.getCellStyle()); | |
109 | + clearCell(cell); | |
110 | + } | |
111 | + if (HandlerConstant.APPOINT_LINE_STYLE.equals(moduleContext)) { | |
112 | + template.appointLineStyle.put(cell.getRowIndex(), cell.getCellStyle()); | |
113 | + clearCell(cell); | |
114 | + } | |
115 | + if (HandlerConstant.SINGLE_LINE_STYLE.equals(moduleContext)) { | |
116 | + template.singleLineStyle = cell.getCellStyle(); | |
117 | + clearCell(cell); | |
118 | + } | |
119 | + if (HandlerConstant.DOUBLE_LINE_STYLE.equals(moduleContext)) { | |
120 | + template.doubleLineStyle = cell.getCellStyle(); | |
121 | + clearCell(cell); | |
122 | + } | |
123 | + } | |
124 | + | |
125 | + private static void clearCell(Cell cell) { | |
126 | + cell.setCellStyle(null); | |
127 | + cell.setCellValue(""); | |
128 | + } | |
129 | + | |
130 | + /*-----------------------------------初始化模板结束-----------------------------------*/ | |
131 | + | |
132 | + /*-----------------------------------数据填充开始------------------------------------*/ | |
133 | + | |
134 | + /** | |
135 | + * 根据map替换相应的常量,通过Map中的值来替换#开头的值 | |
136 | + * | |
137 | + * @param data 替换映射 | |
138 | + */ | |
139 | + public static void extendData(SheetTemplate template, Map<String, String> data) { | |
140 | + if (data == null) { | |
141 | + return; | |
142 | + } | |
143 | + | |
144 | + for (Row row : template.sheet) { | |
145 | + for (Cell c : row) { | |
146 | + if (c.getCellTypeEnum() != CellType.STRING) { | |
147 | + continue; | |
148 | + } | |
149 | + String str = c.getStringCellValue().trim(); | |
150 | + if (str.startsWith("#") && data.containsKey(str.substring(1))) { | |
151 | + c.setCellValue(data.get(str.substring(1))); | |
152 | + } | |
153 | + } | |
154 | + } | |
155 | + } | |
156 | + | |
157 | + /** | |
158 | + * 创建新行,在使用时只要添加完一行,需要调用该方法创建 | |
159 | + */ | |
160 | + public static void createNewRow(SheetTemplate template) { | |
161 | + if (template.lastRowIndex > template.currentRowIndex && template.currentRowIndex != template.initRowIndex) { | |
162 | + template.sheet.shiftRows(template.currentRowIndex, template.lastRowIndex, 1, true, true); | |
163 | + template.lastRowIndex++; | |
164 | + } | |
165 | + template.currentRow = template.sheet.createRow(template.currentRowIndex); | |
166 | + template.currentRow.setHeightInPoints(template.rowHeight); | |
167 | + template.currentRowIndex++; | |
168 | + template.currentColumnIndex = template.initColumnIndex; | |
169 | + } | |
170 | + | |
171 | + /** | |
172 | + * 插入序号,会自动找相应的序号标示的位置完成插入 | |
173 | + * | |
174 | + * @param styleKey 样式标识 | |
175 | + */ | |
176 | + public static void insertSerial(SheetTemplate template, String styleKey) { | |
177 | + if (template.serialNumberColumnIndex < 0) { | |
178 | + return; | |
179 | + } | |
180 | + | |
181 | + template.serialNumber++; | |
182 | + Cell c = template.currentRow.createCell(template.serialNumberColumnIndex); | |
183 | + setCellStyle(template, c, styleKey); | |
184 | + c.setCellValue(template.serialNumber); | |
185 | + } | |
186 | + | |
187 | + /** | |
188 | + * <p>设置Excel元素样式及内容</p> | |
189 | + * | |
190 | + * @param value 内容 | |
191 | + * @param styleKey 样式 | |
192 | + */ | |
193 | + public static void createCell(SheetTemplate template, Object value, String styleKey) { | |
194 | + Cell cell = template.currentRow.createCell(template.currentColumnIndex); | |
195 | + setCellStyle(template, cell, styleKey); | |
196 | + if (null == value || "".equals(value)) { | |
197 | + template.currentColumnIndex++; | |
198 | + return; | |
199 | + } | |
200 | + | |
201 | + if (String.class == value.getClass()) { | |
202 | + cell.setCellValue((String) value); | |
203 | + template.currentColumnIndex++; | |
204 | + return; | |
205 | + } | |
206 | + | |
207 | + if (int.class == value.getClass()) { | |
208 | + cell.setCellValue((int) value); | |
209 | + template.currentColumnIndex++; | |
210 | + return; | |
211 | + } | |
212 | + | |
213 | + if (Integer.class == value.getClass()) { | |
214 | + cell.setCellValue((Integer) value); | |
215 | + template.currentColumnIndex++; | |
216 | + return; | |
217 | + } | |
218 | + | |
219 | + if (double.class == value.getClass()) { | |
220 | + cell.setCellValue((double) value); | |
221 | + template.currentColumnIndex++; | |
222 | + return; | |
223 | + } | |
224 | + | |
225 | + if (Double.class == value.getClass()) { | |
226 | + cell.setCellValue((Double) value); | |
227 | + template.currentColumnIndex++; | |
228 | + return; | |
229 | + } | |
230 | + | |
231 | + if (Date.class == value.getClass()) { | |
232 | + cell.setCellValue((Date) value); | |
233 | + template.currentColumnIndex++; | |
234 | + return; | |
235 | + } | |
236 | + | |
237 | + if (boolean.class == value.getClass()) { | |
238 | + cell.setCellValue((boolean) value); | |
239 | + template.currentColumnIndex++; | |
240 | + return; | |
241 | + } | |
242 | + | |
243 | + if (Boolean.class == value.getClass()) { | |
244 | + cell.setCellValue((Boolean) value); | |
245 | + template.currentColumnIndex++; | |
246 | + return; | |
247 | + } | |
248 | + | |
249 | + if (Calendar.class == value.getClass()) { | |
250 | + cell.setCellValue((Calendar) value); | |
251 | + template.currentColumnIndex++; | |
252 | + return; | |
253 | + } | |
254 | + | |
255 | + if (RichTextString.class == value.getClass()) { | |
256 | + cell.setCellValue((RichTextString) value); | |
257 | + template.currentColumnIndex++; | |
258 | + return; | |
259 | + } | |
260 | + // default value#toString | |
261 | + cell.setCellValue(value.toString()); | |
262 | + template.currentColumnIndex++; | |
263 | + } | |
264 | + | |
265 | + /** | |
266 | + * 设置某个元素的样式 | |
267 | + * | |
268 | + * @param cell cell元素 | |
269 | + * @param styleKey 样式标识 | |
270 | + */ | |
271 | + private static void setCellStyle(SheetTemplate template, Cell cell, String styleKey) { | |
272 | + if (null != styleKey && null != template.classifyStyle.get(styleKey)) { | |
273 | + cell.setCellStyle(template.classifyStyle.get(styleKey)); | |
274 | + return; | |
275 | + } | |
276 | + | |
277 | + if (null != template.appointLineStyle && template.appointLineStyle.containsKey(cell.getRowIndex())) { | |
278 | + cell.setCellStyle(template.appointLineStyle.get(cell.getRowIndex())); | |
279 | + return; | |
280 | + } | |
281 | + if (null != template.singleLineStyle && (cell.getRowIndex() % 2 != 0)) { | |
282 | + cell.setCellStyle(template.singleLineStyle); | |
283 | + return; | |
284 | + } | |
285 | + if (null != template.doubleLineStyle && (cell.getRowIndex() % 2 == 0)) { | |
286 | + cell.setCellStyle(template.doubleLineStyle); | |
287 | + return; | |
288 | + } | |
289 | + if (null != template.defaultStyle) { | |
290 | + cell.setCellStyle(template.defaultStyle); | |
291 | + } | |
292 | + | |
293 | + } | |
294 | + | |
295 | + /*-----------------------------------数据填充结束-----------------------------------*/ | |
296 | + | |
297 | +} | ... | ... |
src/main/java/com/order/erp/common/excel4j/utils/DateUtils.java
0 → 100644
1 | +package com.order.erp.common.excel4j.utils; | |
2 | + | |
3 | +import com.order.erp.common.excel4j.exceptions.TimeMatchFormatException; | |
4 | + | |
5 | +import java.text.ParseException; | |
6 | +import java.text.SimpleDateFormat; | |
7 | +import java.util.Date; | |
8 | + | |
9 | +/** | |
10 | + * <p>时间处理工具类</p> | |
11 | + * author : Crab2Died | |
12 | + * date : 2017/5/23 10:35 | |
13 | + */ | |
14 | +public class DateUtils { | |
15 | + | |
16 | + public static final String DATE_FORMAT_DAY = "yyyy-MM-dd"; | |
17 | + public static final String DATE_FORMAT_DAY_2 = "yyyy/MM/dd"; | |
18 | + public static final String TIME_FORMAT_SEC = "HH:mm:ss"; | |
19 | + public static final String DATE_FORMAT_SEC = "yyyy-MM-dd HH:mm:ss"; | |
20 | + public static final String DATE_FORMAT_MSEC = "yyyy-MM-dd HH:mm:ss.SSS"; | |
21 | + public static final String DATE_FORMAT_MSEC_T = "yyyy-MM-dd'T'HH:mm:ss.SSS"; | |
22 | + public static final String DATE_FORMAT_MSEC_T_Z = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"; | |
23 | + public static final String DATE_FORMAT_DAY_SIMPLE = "y/M/d"; | |
24 | + | |
25 | + /** | |
26 | + * 匹配yyyy-MM-dd | |
27 | + */ | |
28 | + private static final String DATE_REG = "^[1-9]\\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$"; | |
29 | + /** | |
30 | + * 匹配yyyy/MM/dd | |
31 | + */ | |
32 | + private static final String DATE_REG_2 = "^[1-9]\\d{3}/(0[1-9]|1[0-2])/(0[1-9]|[1-2][0-9]|3[0-1])$"; | |
33 | + /** | |
34 | + * 匹配y/M/d | |
35 | + */ | |
36 | + private static final String DATE_REG_SIMPLE_2 = "^[1-9]\\d{3}/([1-9]|1[0-2])/([1-9]|[1-2][0-9]|3[0-1])$"; | |
37 | + /** | |
38 | + * 匹配HH:mm:ss | |
39 | + */ | |
40 | + private static final String TIME_SEC_REG = "^(20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d$"; | |
41 | + /** | |
42 | + * 匹配yyyy-MM-dd HH:mm:ss | |
43 | + */ | |
44 | + private static final String DATE_TIME_REG = "^[1-9]\\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])\\s" + | |
45 | + "(20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d$"; | |
46 | + /** | |
47 | + * 匹配yyyy-MM-dd HH:mm:ss.SSS | |
48 | + */ | |
49 | + private static final String DATE_TIME_MSEC_REG = "^[1-9]\\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])\\s" + | |
50 | + "(20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d\\.\\d{3}$"; | |
51 | + /** | |
52 | + * 匹配yyyy-MM-dd'T'HH:mm:ss.SSS | |
53 | + */ | |
54 | + private static final String DATE_TIME_MSEC_T_REG = "^[1-9]\\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])T" + | |
55 | + "(20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d\\.\\d{3}$"; | |
56 | + /** | |
57 | + * 匹配yyyy-MM-dd'T'HH:mm:ss.SSS'Z' | |
58 | + */ | |
59 | + private static final String DATE_TIME_MSEC_T_Z_REG = "^[1-9]\\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])T" + | |
60 | + "(20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d\\.\\d{3}Z$"; | |
61 | + | |
62 | + /** | |
63 | + * <p>将{@link Date}类型转换为指定格式的字符串</p> | |
64 | + * author : Crab2Died | |
65 | + * date : 2017年06月02日 15:32:04 | |
66 | + * | |
67 | + * @param date {@link Date}类型的时间 | |
68 | + * @param format 指定格式化类型 | |
69 | + * @return 返回格式化后的时间字符串 | |
70 | + */ | |
71 | + public static String date2Str(Date date, String format) { | |
72 | + SimpleDateFormat sdf = new SimpleDateFormat(format); | |
73 | + return sdf.format(date); | |
74 | + } | |
75 | + | |
76 | + /** | |
77 | + * <p>将{@link Date}类型转换为默认为[yyyy-MM-dd HH:mm:ss]类型的字符串</p> | |
78 | + * author : Crab2Died | |
79 | + * date : 2017年06月02日 15:30:01 | |
80 | + * | |
81 | + * @param date {@link Date}类型的时间 | |
82 | + * @return 返回格式化后的时间字符串 | |
83 | + */ | |
84 | + public static String date2Str(Date date) { | |
85 | + SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_SEC); | |
86 | + return sdf.format(date); | |
87 | + } | |
88 | + | |
89 | + /** | |
90 | + * <p>根据给出的格式化类型将时间字符串转为{@link Date}类型</p> | |
91 | + * author : Crab2Died | |
92 | + * date : 2017年06月02日 15:27:22 | |
93 | + * | |
94 | + * @param strDate 时间字符串 | |
95 | + * @param format 格式化类型 | |
96 | + * @return 返回{@link java.util.Date}类型 | |
97 | + */ | |
98 | + public static Date str2Date(String strDate, String format) { | |
99 | + Date date = null; | |
100 | + SimpleDateFormat sdf = new SimpleDateFormat(format); | |
101 | + try { | |
102 | + date = sdf.parse(strDate); | |
103 | + } catch (ParseException e) { | |
104 | + throw new TimeMatchFormatException("[" + strDate + "] parse to [" + format + "] exception", e); | |
105 | + } | |
106 | + return date; | |
107 | + } | |
108 | + | |
109 | + /** | |
110 | + * <p>字符串时间转为{@link Date}类型, | |
111 | + * 未找到匹配类型则抛出{@link TimeMatchFormatException}异常</p> | |
112 | + * <p>支持匹配类型列表:</p> | |
113 | + * <p>yyyy-MM-dd</p> | |
114 | + * <p>yyyy/MM/dd</p> | |
115 | + * <p>HH:mm:ss</p> | |
116 | + * <p>yyyy-MM-dd HH:mm:ss</p> | |
117 | + * <p>yyyy-MM-dd'T'HH:mm:ss.SSS</p> | |
118 | + * <p>yyyy-MM-dd'T'HH:mm:ss.SSS'Z'</p> | |
119 | + * <p> | |
120 | + * author : Crab2Died | |
121 | + * date : 2017年06月02日 15:21:54 | |
122 | + * | |
123 | + * @param strDate 时间字符串 | |
124 | + * @return Date {@link Date}时间 | |
125 | + * @throws ParseException 异常 | |
126 | + */ | |
127 | + public static Date str2Date(String strDate) throws ParseException { | |
128 | + | |
129 | + strDate = strDate.trim(); | |
130 | + SimpleDateFormat sdf = null; | |
131 | + if (RegularUtils.isMatched(strDate, DATE_REG)) { | |
132 | + sdf = new SimpleDateFormat(DATE_FORMAT_DAY); | |
133 | + } | |
134 | + if (RegularUtils.isMatched(strDate, DATE_REG_2)) { | |
135 | + sdf = new SimpleDateFormat(DATE_FORMAT_DAY_2); | |
136 | + } | |
137 | + if (RegularUtils.isMatched(strDate, DATE_REG_SIMPLE_2)) { | |
138 | + sdf = new SimpleDateFormat(DATE_FORMAT_DAY_SIMPLE); | |
139 | + } | |
140 | + if (RegularUtils.isMatched(strDate, TIME_SEC_REG)) { | |
141 | + sdf = new SimpleDateFormat(TIME_FORMAT_SEC); | |
142 | + } | |
143 | + if (RegularUtils.isMatched(strDate, DATE_TIME_REG)) { | |
144 | + sdf = new SimpleDateFormat(DATE_FORMAT_SEC); | |
145 | + } | |
146 | + if (RegularUtils.isMatched(strDate, DATE_TIME_MSEC_REG)) { | |
147 | + sdf = new SimpleDateFormat(DATE_FORMAT_MSEC); | |
148 | + } | |
149 | + if (RegularUtils.isMatched(strDate, DATE_TIME_MSEC_T_REG)) { | |
150 | + sdf = new SimpleDateFormat(DATE_FORMAT_MSEC_T); | |
151 | + } | |
152 | + if (RegularUtils.isMatched(strDate, DATE_TIME_MSEC_T_Z_REG)) { | |
153 | + sdf = new SimpleDateFormat(DATE_FORMAT_MSEC_T_Z); | |
154 | + } | |
155 | + if (null != sdf) { | |
156 | + return sdf.parse(strDate); | |
157 | + } | |
158 | + throw new TimeMatchFormatException( | |
159 | + String.format("[%s] can not matching right time format", strDate)); | |
160 | + } | |
161 | + | |
162 | + /** | |
163 | + * <p>字符串时间转为{@link Date}类型,未找到匹配类型则返NULL</p> | |
164 | + * <p>支持匹配类型列表:</p> | |
165 | + * <p>yyyy-MM-dd</p> | |
166 | + * <p>yyyy/MM/dd</p> | |
167 | + * <p>HH:mm:ss</p> | |
168 | + * <p>yyyy-MM-dd HH:mm:ss</p> | |
169 | + * <p>yyyy-MM-dTHH:mm:ss.SSS</p> | |
170 | + * <p> | |
171 | + * author : Crab2Died | |
172 | + * date : 2017年06月02日 15:21:54 | |
173 | + * | |
174 | + * @param strDate 时间字符串 | |
175 | + * @return Date {@link Date}时间 | |
176 | + */ | |
177 | + public static Date str2DateUnmatch2Null(String strDate) { | |
178 | + Date date; | |
179 | + try { | |
180 | + date = str2Date(strDate); | |
181 | + } catch (Exception e) { | |
182 | + throw new TimeMatchFormatException("[" + strDate + "] date auto parse exception", e); | |
183 | + } | |
184 | + return date; | |
185 | + } | |
186 | + | |
187 | +} | ... | ... |
src/main/java/com/order/erp/common/excel4j/utils/RegularUtils.java
0 → 100644
1 | +package com.order.erp.common.excel4j.utils; | |
2 | + | |
3 | + | |
4 | + | |
5 | +import com.order.erp.common.excel4j.exceptions.IllegalGroupIndexException; | |
6 | + | |
7 | +import java.util.ArrayList; | |
8 | +import java.util.List; | |
9 | +import java.util.regex.Matcher; | |
10 | +import java.util.regex.Pattern; | |
11 | + | |
12 | +/** | |
13 | + * <p>正则匹配相关工具</p> | |
14 | + * author : Crab2Died | |
15 | + * date : 2017/5/24 9:43 | |
16 | + */ | |
17 | +public class RegularUtils { | |
18 | + | |
19 | + private static Pattern compile = Pattern.compile("^(\\d+)(\\.0*)?$"); | |
20 | + | |
21 | + /** | |
22 | + * <p>判断内容是否匹配</p> | |
23 | + * author : Crab2Died | |
24 | + * date : 2017年06月02日 15:46:25 | |
25 | + * | |
26 | + * @param pattern 匹配目标内容 | |
27 | + * @param reg 正则表达式 | |
28 | + * @return 返回boolean | |
29 | + */ | |
30 | + public static boolean isMatched(String pattern, String reg) { | |
31 | + Pattern compile = Pattern.compile(reg); | |
32 | + return compile.matcher(pattern).matches(); | |
33 | + } | |
34 | + | |
35 | + /** | |
36 | + * <p>正则提取匹配到的内容</p> | |
37 | + * <p>例如:</p> | |
38 | + * <p> | |
39 | + * author : Crab2Died | |
40 | + * date : 2017年06月02日 15:49:51 | |
41 | + * | |
42 | + * @param pattern 匹配目标内容 | |
43 | + * @param reg 正则表达式 | |
44 | + * @param group 提取内容索引 | |
45 | + * @return 提取内容集合 | |
46 | + */ | |
47 | + public static List<String> match(String pattern, String reg, int group) { | |
48 | + | |
49 | + List<String> matchGroups = new ArrayList<>(); | |
50 | + Pattern compile = Pattern.compile(reg); | |
51 | + Matcher matcher = compile.matcher(pattern); | |
52 | + if (group > matcher.groupCount() || group < 0) { | |
53 | + throw new IllegalGroupIndexException("Illegal match group :" + group); | |
54 | + } | |
55 | + while (matcher.find()) { | |
56 | + matchGroups.add(matcher.group(group)); | |
57 | + } | |
58 | + return matchGroups; | |
59 | + } | |
60 | + | |
61 | + /** | |
62 | + * <p>正则提取匹配到的内容,默认提取索引为0</p> | |
63 | + * <p>例如:</p> | |
64 | + * <p> | |
65 | + * author : Crab2Died | |
66 | + * date : 2017年06月02日 15:49:51 | |
67 | + * | |
68 | + * @param pattern 匹配目标内容 | |
69 | + * @param reg 正则表达式 | |
70 | + * @return 提取内容集合 | |
71 | + */ | |
72 | + public static String match(String pattern, String reg) { | |
73 | + | |
74 | + String match = null; | |
75 | + List<String> matches = match(pattern, reg, 0); | |
76 | + if (null != matches && matches.size() > 0) { | |
77 | + match = matches.get(0); | |
78 | + } | |
79 | + return match; | |
80 | + } | |
81 | + | |
82 | + public static String converNumByReg(String number) { | |
83 | + | |
84 | + Matcher matcher = compile.matcher(number); | |
85 | + while (matcher.find()) { | |
86 | + number = matcher.group(1); | |
87 | + } | |
88 | + return number; | |
89 | + } | |
90 | +} | ... | ... |
src/main/java/com/order/erp/common/excel4j/utils/Utils.java
0 → 100644
1 | +package com.order.erp.common.excel4j.utils; | |
2 | + | |
3 | +import com.order.erp.common.excel4j.annotation.ExcelField; | |
4 | +import com.order.erp.common.excel4j.converter.DefaultConvertible; | |
5 | +import com.order.erp.common.excel4j.converter.WriteConvertible; | |
6 | +import com.order.erp.common.excel4j.exceptions.Excel4JException; | |
7 | +import com.order.erp.common.excel4j.handler.ExcelHeader; | |
8 | +import org.apache.poi.ss.usermodel.Cell; | |
9 | +import org.apache.poi.ss.usermodel.CellValue; | |
10 | +import org.apache.poi.ss.usermodel.DateUtil; | |
11 | +import org.apache.poi.ss.usermodel.Row; | |
12 | + | |
13 | +import java.beans.BeanInfo; | |
14 | +import java.beans.IntrospectionException; | |
15 | +import java.beans.Introspector; | |
16 | +import java.beans.PropertyDescriptor; | |
17 | +import java.lang.reflect.Field; | |
18 | +import java.lang.reflect.InvocationTargetException; | |
19 | +import java.lang.reflect.Method; | |
20 | +import java.math.BigDecimal; | |
21 | +import java.util.*; | |
22 | +import java.util.regex.Pattern; | |
23 | + | |
24 | +/** | |
25 | + * Excel4J工具类 | |
26 | + */ | |
27 | +public class Utils { | |
28 | + | |
29 | + /** | |
30 | + * getter或setter枚举 | |
31 | + */ | |
32 | + public enum FieldAccessType { | |
33 | + | |
34 | + GETTER, SETTER | |
35 | + } | |
36 | + | |
37 | + /** | |
38 | + * <p>根据JAVA对象注解获取Excel表头信息</p> | |
39 | + * | |
40 | + * @param clz 类型 | |
41 | + * @return 表头信息 | |
42 | + */ | |
43 | + public static List<ExcelHeader> getHeaderList(Class<?> clz) throws Excel4JException { | |
44 | + | |
45 | + List<ExcelHeader> headers = new ArrayList<>(); | |
46 | + List<Field> fields = new ArrayList<>(); | |
47 | + for (Class<?> clazz = clz; clazz != Object.class; clazz = clazz.getSuperclass()) { | |
48 | + fields.addAll(Arrays.asList(clazz.getDeclaredFields())); | |
49 | + } | |
50 | + for (Field field : fields) { | |
51 | + // 是否使用ExcelField注解 | |
52 | + if (field.isAnnotationPresent(ExcelField.class)) { | |
53 | + ExcelField er = field.getAnnotation(ExcelField.class); | |
54 | + try { | |
55 | + headers.add(new ExcelHeader( | |
56 | + er.title(), | |
57 | + er.order(), | |
58 | + er.writeConverter().newInstance(), | |
59 | + er.readConverter().newInstance(), | |
60 | + field.getName(), | |
61 | + field.getType() | |
62 | + )); | |
63 | + } catch (InstantiationException | IllegalAccessException e) { | |
64 | + throw new Excel4JException(e); | |
65 | + } | |
66 | + } | |
67 | + } | |
68 | + Collections.sort(headers); | |
69 | + return headers; | |
70 | + } | |
71 | + | |
72 | + /** | |
73 | + * 获取excel列表头 | |
74 | + * | |
75 | + * @param titleRow excel行 | |
76 | + * @param clz 类型 | |
77 | + * @return ExcelHeader集合 | |
78 | + * @throws Excel4JException 异常 | |
79 | + */ | |
80 | + public static Map<Integer, ExcelHeader> getHeaderMap(Row titleRow, Class<?> clz) | |
81 | + throws Excel4JException { | |
82 | + | |
83 | + List<ExcelHeader> headers = getHeaderList(clz); | |
84 | + Map<Integer, ExcelHeader> maps = new HashMap<>(); | |
85 | + for (Cell c : titleRow) { | |
86 | + String title = c.getStringCellValue(); | |
87 | + for (ExcelHeader eh : headers) { | |
88 | + if (eh.getTitle().equals(title.trim())) { | |
89 | + maps.put(c.getColumnIndex(), eh); | |
90 | + break; | |
91 | + } | |
92 | + } | |
93 | + } | |
94 | + return maps; | |
95 | + } | |
96 | + | |
97 | + /** | |
98 | + * 获取单元格内容 | |
99 | + * | |
100 | + * @param c 单元格 | |
101 | + * @return 单元格内容 | |
102 | + */ | |
103 | + public static String getCellValue(Cell c) { | |
104 | + String o; | |
105 | + switch (c.getCellTypeEnum()) { | |
106 | + case BLANK: | |
107 | + o = ""; | |
108 | + break; | |
109 | + case BOOLEAN: | |
110 | + o = String.valueOf(c.getBooleanCellValue()); | |
111 | + break; | |
112 | + case FORMULA: | |
113 | + o = calculationFormula(c); | |
114 | + break; | |
115 | + case NUMERIC: | |
116 | + if (DateUtil.isCellDateFormatted(c)) { | |
117 | + o = DateUtils.date2Str(c.getDateCellValue()); | |
118 | + } else { | |
119 | + o = String.valueOf(c.getNumericCellValue()); | |
120 | + o = matchDoneBigDecimal(o); | |
121 | + o = RegularUtils.converNumByReg(o); | |
122 | + } | |
123 | + break; | |
124 | + case STRING: | |
125 | + o = c.getStringCellValue(); | |
126 | + break; | |
127 | + default: | |
128 | + o = null; | |
129 | + break; | |
130 | + } | |
131 | + return o; | |
132 | + } | |
133 | + | |
134 | + /** | |
135 | + * 字符串转对象 | |
136 | + * | |
137 | + * @param strField 字符串 | |
138 | + * @param clazz 待转类型 | |
139 | + * @return 转换后数据 | |
140 | + */ | |
141 | + public static Object str2TargetClass(String strField, Class<?> clazz) { | |
142 | + if (null == strField || "".equals(strField)) { | |
143 | + return null; | |
144 | + } | |
145 | + if ((Long.class == clazz) || (long.class == clazz)) { | |
146 | + strField = matchDoneBigDecimal(strField); | |
147 | + strField = RegularUtils.converNumByReg(strField); | |
148 | + return Long.parseLong(strField); | |
149 | + } | |
150 | + if ((Integer.class == clazz) || (int.class == clazz)) { | |
151 | + strField = matchDoneBigDecimal(strField); | |
152 | + strField = RegularUtils.converNumByReg(strField); | |
153 | + return Integer.parseInt(strField); | |
154 | + } | |
155 | + if ((Float.class == clazz) || (float.class == clazz)) { | |
156 | + strField = matchDoneBigDecimal(strField); | |
157 | + return Float.parseFloat(strField); | |
158 | + } | |
159 | + if ((Double.class == clazz) || (double.class == clazz)) { | |
160 | + strField = matchDoneBigDecimal(strField); | |
161 | + return Double.parseDouble(strField); | |
162 | + } | |
163 | + if ((Character.class == clazz) || (char.class == clazz)) { | |
164 | + return strField.toCharArray()[0]; | |
165 | + } | |
166 | + if ((Boolean.class == clazz) || (boolean.class == clazz)) { | |
167 | + return Boolean.parseBoolean(strField); | |
168 | + } | |
169 | + if (Date.class == clazz) { | |
170 | + return DateUtils.str2DateUnmatch2Null(strField); | |
171 | + } | |
172 | + return strField; | |
173 | + } | |
174 | + | |
175 | + /** | |
176 | + * 科学计数法数据转换 | |
177 | + * | |
178 | + * @param bigDecimal 科学计数法 | |
179 | + * @return 数据字符串 | |
180 | + */ | |
181 | + private static String matchDoneBigDecimal(String bigDecimal) { | |
182 | + // 对科学计数法进行处理 | |
183 | + boolean flg = Pattern.matches("^-?\\d+(\\.\\d+)?(E-?\\d+)?$", bigDecimal); | |
184 | + if (flg) { | |
185 | + BigDecimal bd = new BigDecimal(bigDecimal); | |
186 | + bigDecimal = bd.toPlainString(); | |
187 | + } | |
188 | + return bigDecimal; | |
189 | + } | |
190 | + | |
191 | + /** | |
192 | + * <p>根据java对象属性{@link Field}获取该属性的getter或setter方法名, | |
193 | + * 另对{@link boolean}及{@link Boolean}做了行管处理</p> | |
194 | + * | |
195 | + * @param clazz 操作对象 | |
196 | + * @param fieldName 对象属性 | |
197 | + * @param methodType 方法类型,getter或setter枚举 | |
198 | + * @return getter或setter方法 | |
199 | + * @throws IntrospectionException 异常 | |
200 | + * @author Crab2Died | |
201 | + */ | |
202 | + public static Method getterOrSetter(Class clazz, String fieldName, FieldAccessType methodType) | |
203 | + throws IntrospectionException { | |
204 | + | |
205 | + if (null == fieldName || "".equals(fieldName)) { | |
206 | + return null; | |
207 | + } | |
208 | + | |
209 | + BeanInfo beanInfo = Introspector.getBeanInfo(clazz); | |
210 | + PropertyDescriptor[] props = beanInfo.getPropertyDescriptors(); | |
211 | + for (PropertyDescriptor prop : props) { | |
212 | + if (fieldName.equals(prop.getName())) { | |
213 | + if (FieldAccessType.SETTER == methodType) { | |
214 | + return prop.getWriteMethod(); | |
215 | + } | |
216 | + if (FieldAccessType.GETTER == methodType) { | |
217 | + return prop.getReadMethod(); | |
218 | + } | |
219 | + } | |
220 | + } | |
221 | + throw new IntrospectionException("Can not get the getter or setter method"); | |
222 | + } | |
223 | + | |
224 | + /** | |
225 | + * <p>根据对象的属性名{@code fieldName}获取某个java的属性{@link Field}</p> | |
226 | + * | |
227 | + * @param clazz java对象的class属性 | |
228 | + * @param fieldName 属性名 | |
229 | + * @return {@link Field} java对象的属性 | |
230 | + * @author Crab2Died | |
231 | + */ | |
232 | + private static Field matchClassField(Class clazz, String fieldName) { | |
233 | + | |
234 | + List<Field> fields = new ArrayList<>(); | |
235 | + for (; clazz != Object.class; clazz = clazz.getSuperclass()) { | |
236 | + fields.addAll(Arrays.asList(clazz.getDeclaredFields())); | |
237 | + } | |
238 | + for (Field field : fields) { | |
239 | + if (fieldName.equals(field.getName())) { | |
240 | + return field; | |
241 | + } | |
242 | + } | |
243 | + throw new IllegalArgumentException("[" + clazz.getName() + "] can`t found field with [" + fieldName + "]"); | |
244 | + } | |
245 | + | |
246 | + /** | |
247 | + * 根据属性名与属性类型获取字段内容 | |
248 | + * | |
249 | + * @param bean 对象 | |
250 | + * @param fieldName 字段名 | |
251 | + * @param writeConvertible 写入转换器 | |
252 | + * @return 对象指定字段内容 | |
253 | + * @throws Excel4JException 异常 | |
254 | + */ | |
255 | + public static String getProperty(Object bean, String fieldName, WriteConvertible writeConvertible) | |
256 | + throws Excel4JException { | |
257 | + | |
258 | + if (bean == null || fieldName == null) { | |
259 | + throw new IllegalArgumentException("Operating bean or filed class must not be null"); | |
260 | + } | |
261 | + Method method; | |
262 | + Object object; | |
263 | + try { | |
264 | + method = getterOrSetter(bean.getClass(), fieldName, FieldAccessType.GETTER); | |
265 | + object = method.invoke(bean); | |
266 | + } catch (IntrospectionException | IllegalAccessException | InvocationTargetException e) { | |
267 | + throw new Excel4JException(e); | |
268 | + } | |
269 | + if (null != writeConvertible && writeConvertible.getClass() != DefaultConvertible.class) { | |
270 | + // 写入转换器 | |
271 | + object = writeConvertible.execWrite(object); | |
272 | + } | |
273 | + return object == null ? "" : object.toString(); | |
274 | + } | |
275 | + | |
276 | + /** | |
277 | + * 根据属性名与属性类型获取字段内容 | |
278 | + * | |
279 | + * @param bean 对象 | |
280 | + * @param name 字段名 | |
281 | + * @param value 字段类型 | |
282 | + */ | |
283 | + public static void copyProperty(Object bean, String name, Object value) | |
284 | + throws Excel4JException { | |
285 | + | |
286 | + if (null == name || null == value) { | |
287 | + return; | |
288 | + } | |
289 | + Field field = matchClassField(bean.getClass(), name); | |
290 | + if (null == field) { | |
291 | + return; | |
292 | + } | |
293 | + Method method; | |
294 | + try { | |
295 | + method = getterOrSetter(bean.getClass(), name, FieldAccessType.SETTER); | |
296 | + | |
297 | + if (value.getClass() == field.getType()) { | |
298 | + method.invoke(bean, value); | |
299 | + } else { | |
300 | + method.invoke(bean, str2TargetClass(value.toString(), field.getType())); | |
301 | + } | |
302 | + } catch (IntrospectionException | IllegalAccessException | InvocationTargetException e) { | |
303 | + throw new Excel4JException(e); | |
304 | + } | |
305 | + | |
306 | + } | |
307 | + | |
308 | + /** | |
309 | + * 计算公式结果 | |
310 | + * | |
311 | + * @param cell 单元格类型为公式的单元格 | |
312 | + * @return 返回单元格计算后的值 格式化成String | |
313 | + * @author QingMings | |
314 | + * Email:1821063757@qq.com | |
315 | + * date 2018-01-13 | |
316 | + */ | |
317 | + public static String calculationFormula(Cell cell) { | |
318 | + | |
319 | + CellValue cellValue = cell.getSheet().getWorkbook().getCreationHelper() | |
320 | + .createFormulaEvaluator().evaluate(cell); | |
321 | + return cellValue.formatAsString(); | |
322 | + } | |
323 | +} | ... | ... |
src/main/java/com/order/erp/common/excel4j/wrapper/MapSheetWrapper.java
0 → 100644
1 | +package com.order.erp.common.excel4j.wrapper; | |
2 | + | |
3 | +import java.util.List; | |
4 | +import java.util.Map; | |
5 | + | |
6 | +/** | |
7 | + * <p>基于模板、注解的Map数据导出的sheet包装类</p> | |
8 | + */ | |
9 | +public class MapSheetWrapper { | |
10 | + | |
11 | + /** | |
12 | + * sheet序号 | |
13 | + */ | |
14 | + private int sheetIndex; | |
15 | + | |
16 | + /** | |
17 | + * 表格行数据 | |
18 | + */ | |
19 | + private Map<String, List<?>> data; | |
20 | + | |
21 | + /** | |
22 | + * 扩展数据 | |
23 | + */ | |
24 | + private Map<String, String> extendMap; | |
25 | + | |
26 | + /** | |
27 | + * 注解的class | |
28 | + */ | |
29 | + private Class clazz; | |
30 | + | |
31 | + /** | |
32 | + * 是否写表头 | |
33 | + */ | |
34 | + private boolean isWriteHeader; | |
35 | + | |
36 | + public MapSheetWrapper() { | |
37 | + } | |
38 | + | |
39 | + public MapSheetWrapper(Map<String, List<?>> data, Class clazz) { | |
40 | + this.data = data; | |
41 | + this.clazz = clazz; | |
42 | + } | |
43 | + | |
44 | + public MapSheetWrapper(int sheetIndex, Map<String, List<?>> data, Class clazz) { | |
45 | + this.sheetIndex = sheetIndex; | |
46 | + this.data = data; | |
47 | + this.clazz = clazz; | |
48 | + } | |
49 | + | |
50 | + public MapSheetWrapper(Map<String, List<?>> data, Map<String, String> extendMap, Class clazz) { | |
51 | + this.data = data; | |
52 | + this.extendMap = extendMap; | |
53 | + this.clazz = clazz; | |
54 | + } | |
55 | + | |
56 | + public MapSheetWrapper(int sheetIndex, Map<String, List<?>> data, Map<String, String> extendMap, Class clazz, | |
57 | + boolean isWriteHeader) { | |
58 | + this.sheetIndex = sheetIndex; | |
59 | + this.data = data; | |
60 | + this.extendMap = extendMap; | |
61 | + this.clazz = clazz; | |
62 | + this.isWriteHeader = isWriteHeader; | |
63 | + } | |
64 | + | |
65 | + public int getSheetIndex() { | |
66 | + return sheetIndex; | |
67 | + } | |
68 | + | |
69 | + public void setSheetIndex(int sheetIndex) { | |
70 | + this.sheetIndex = sheetIndex; | |
71 | + } | |
72 | + | |
73 | + public Map<String, List<?>> getData() { | |
74 | + return data; | |
75 | + } | |
76 | + | |
77 | + public void setData(Map<String, List<?>> data) { | |
78 | + this.data = data; | |
79 | + } | |
80 | + | |
81 | + public Map<String, String> getExtendMap() { | |
82 | + return extendMap; | |
83 | + } | |
84 | + | |
85 | + public void setExtendMap(Map<String, String> extendMap) { | |
86 | + this.extendMap = extendMap; | |
87 | + } | |
88 | + | |
89 | + public Class getClazz() { | |
90 | + return clazz; | |
91 | + } | |
92 | + | |
93 | + public void setClazz(Class clazz) { | |
94 | + this.clazz = clazz; | |
95 | + } | |
96 | + | |
97 | + public boolean isWriteHeader() { | |
98 | + return isWriteHeader; | |
99 | + } | |
100 | + | |
101 | + public void setWriteHeader(boolean writeHeader) { | |
102 | + isWriteHeader = writeHeader; | |
103 | + } | |
104 | +} | ... | ... |
src/main/java/com/order/erp/common/excel4j/wrapper/NoTemplateSheetWrapper.java
0 → 100644
1 | +package com.order.erp.common.excel4j.wrapper; | |
2 | + | |
3 | +import java.util.List; | |
4 | + | |
5 | +/** | |
6 | + * <p>无模板、基于注解导出的sheet包装类</p> | |
7 | + */ | |
8 | +public class NoTemplateSheetWrapper { | |
9 | + | |
10 | + /** | |
11 | + * 待导出行数据 | |
12 | + */ | |
13 | + private List<?> data; | |
14 | + | |
15 | + /** | |
16 | + * 基于注解的class | |
17 | + */ | |
18 | + private Class clazz; | |
19 | + | |
20 | + /** | |
21 | + * 是否写入表头 | |
22 | + */ | |
23 | + private boolean isWriteHeader; | |
24 | + | |
25 | + /** | |
26 | + * sheet名 | |
27 | + */ | |
28 | + private String sheetName; | |
29 | + | |
30 | + public NoTemplateSheetWrapper() { | |
31 | + } | |
32 | + | |
33 | + public NoTemplateSheetWrapper(List<?> data, Class clazz) { | |
34 | + this.data = data; | |
35 | + this.clazz = clazz; | |
36 | + } | |
37 | + | |
38 | + public NoTemplateSheetWrapper(List<?> data, Class clazz, boolean isWriteHeader) { | |
39 | + this.data = data; | |
40 | + this.clazz = clazz; | |
41 | + this.isWriteHeader = isWriteHeader; | |
42 | + } | |
43 | + | |
44 | + public NoTemplateSheetWrapper(List<?> data, Class clazz, boolean isWriteHeader, String sheetName) { | |
45 | + this.data = data; | |
46 | + this.clazz = clazz; | |
47 | + this.isWriteHeader = isWriteHeader; | |
48 | + this.sheetName = sheetName; | |
49 | + } | |
50 | + | |
51 | + public List<?> getData() { | |
52 | + return data; | |
53 | + } | |
54 | + | |
55 | + public void setData(List<?> data) { | |
56 | + this.data = data; | |
57 | + } | |
58 | + | |
59 | + public Class getClazz() { | |
60 | + return clazz; | |
61 | + } | |
62 | + | |
63 | + public void setClazz(Class clazz) { | |
64 | + this.clazz = clazz; | |
65 | + } | |
66 | + | |
67 | + public boolean isWriteHeader() { | |
68 | + return isWriteHeader; | |
69 | + } | |
70 | + | |
71 | + public void setWriteHeader(boolean writeHeader) { | |
72 | + isWriteHeader = writeHeader; | |
73 | + } | |
74 | + | |
75 | + public String getSheetName() { | |
76 | + return sheetName; | |
77 | + } | |
78 | + | |
79 | + public void setSheetName(String sheetName) { | |
80 | + this.sheetName = sheetName; | |
81 | + } | |
82 | +} | ... | ... |
src/main/java/com/order/erp/common/excel4j/wrapper/NormalSheetWrapper.java
0 → 100644
1 | +package com.order.erp.common.excel4j.wrapper; | |
2 | + | |
3 | +import java.util.List; | |
4 | +import java.util.Map; | |
5 | + | |
6 | +/** | |
7 | + * <p>基于模板、注解的通用sheet包装类</p> | |
8 | + */ | |
9 | +public class NormalSheetWrapper { | |
10 | + | |
11 | + /** | |
12 | + * sheet的序号 | |
13 | + */ | |
14 | + private int sheetIndex; | |
15 | + | |
16 | + /** | |
17 | + * 表格行数据 | |
18 | + */ | |
19 | + private List<?> data; | |
20 | + | |
21 | + /** | |
22 | + * 扩张数据 | |
23 | + */ | |
24 | + private Map<String, String> extendMap; | |
25 | + | |
26 | + /** | |
27 | + * 基于注解的class | |
28 | + */ | |
29 | + private Class clazz; | |
30 | + | |
31 | + /** | |
32 | + * 是否写入表头 | |
33 | + */ | |
34 | + private boolean isWriteHeader; | |
35 | + | |
36 | + public NormalSheetWrapper() { | |
37 | + } | |
38 | + | |
39 | + public NormalSheetWrapper(List<?> data, Class clazz) { | |
40 | + this.data = data; | |
41 | + this.clazz = clazz; | |
42 | + } | |
43 | + | |
44 | + public NormalSheetWrapper(int sheetIndex, List<?> data, Class clazz) { | |
45 | + this.sheetIndex = sheetIndex; | |
46 | + this.data = data; | |
47 | + this.clazz = clazz; | |
48 | + } | |
49 | + | |
50 | + public NormalSheetWrapper(int sheetIndex, List<?> data, Map<String, String> extendMap, Class clazz, | |
51 | + boolean isWriteHeader) { | |
52 | + this.sheetIndex = sheetIndex; | |
53 | + this.data = data; | |
54 | + this.extendMap = extendMap; | |
55 | + this.clazz = clazz; | |
56 | + this.isWriteHeader = isWriteHeader; | |
57 | + } | |
58 | + | |
59 | + public int getSheetIndex() { | |
60 | + return sheetIndex; | |
61 | + } | |
62 | + | |
63 | + public void setSheetIndex(int sheetIndex) { | |
64 | + this.sheetIndex = sheetIndex; | |
65 | + } | |
66 | + | |
67 | + public List<?> getData() { | |
68 | + return data; | |
69 | + } | |
70 | + | |
71 | + public void setData(List<?> data) { | |
72 | + this.data = data; | |
73 | + } | |
74 | + | |
75 | + public Map<String, String> getExtendMap() { | |
76 | + return extendMap; | |
77 | + } | |
78 | + | |
79 | + public void setExtendMap(Map<String, String> extendMap) { | |
80 | + this.extendMap = extendMap; | |
81 | + } | |
82 | + | |
83 | + public Class getClazz() { | |
84 | + return clazz; | |
85 | + } | |
86 | + | |
87 | + public void setClazz(Class clazz) { | |
88 | + this.clazz = clazz; | |
89 | + } | |
90 | + | |
91 | + public boolean isWriteHeader() { | |
92 | + return isWriteHeader; | |
93 | + } | |
94 | + | |
95 | + public void setWriteHeader(boolean writeHeader) { | |
96 | + isWriteHeader = writeHeader; | |
97 | + } | |
98 | +} | ... | ... |
src/main/java/com/order/erp/common/excel4j/wrapper/SimpleSheetWrapper.java
0 → 100644
1 | +package com.order.erp.common.excel4j.wrapper; | |
2 | + | |
3 | +import java.util.List; | |
4 | + | |
5 | +/** | |
6 | + * <p>无模板,无注解的简单sheet包装类</p> | |
7 | + */ | |
8 | +public class SimpleSheetWrapper { | |
9 | + | |
10 | + /** | |
11 | + * 每个sheet的列表数据 | |
12 | + */ | |
13 | + private List<?> data; | |
14 | + | |
15 | + /** | |
16 | + * 每个sheet的表头 | |
17 | + */ | |
18 | + private List<String> header; | |
19 | + | |
20 | + /** | |
21 | + * 每个sheet的名字 | |
22 | + */ | |
23 | + private String sheetName; | |
24 | + | |
25 | + public SimpleSheetWrapper() { | |
26 | + } | |
27 | + | |
28 | + public SimpleSheetWrapper(List<?> data, List<String> header, String sheetName) { | |
29 | + this.data = data; | |
30 | + this.header = header; | |
31 | + this.sheetName = sheetName; | |
32 | + } | |
33 | + | |
34 | + public SimpleSheetWrapper(List<?> data, List<String> header) { | |
35 | + this.data = data; | |
36 | + this.header = header; | |
37 | + } | |
38 | + | |
39 | + public SimpleSheetWrapper(List<?> data, String sheetName) { | |
40 | + this.data = data; | |
41 | + this.sheetName = sheetName; | |
42 | + } | |
43 | + | |
44 | + public SimpleSheetWrapper(List<?> data) { | |
45 | + this.data = data; | |
46 | + } | |
47 | + | |
48 | + public List<?> getData() { | |
49 | + return data; | |
50 | + } | |
51 | + | |
52 | + public void setData(List<?> data) { | |
53 | + this.data = data; | |
54 | + } | |
55 | + | |
56 | + public List<String> getHeader() { | |
57 | + return header; | |
58 | + } | |
59 | + | |
60 | + public void setHeader(List<String> header) { | |
61 | + this.header = header; | |
62 | + } | |
63 | + | |
64 | + public String getSheetName() { | |
65 | + return sheetName; | |
66 | + } | |
67 | + | |
68 | + public void setSheetName(String sheetName) { | |
69 | + this.sheetName = sheetName; | |
70 | + } | |
71 | +} | ... | ... |
src/main/java/com/order/erp/config/AdminMetaObjectHandler.java
... | ... | @@ -30,14 +30,18 @@ public class AdminMetaObjectHandler implements MetaObjectHandler { |
30 | 30 | this.strictInsertFill(metaObject, CREATE_TIME, LocalDateTime.class, now); |
31 | 31 | this.strictInsertFill(metaObject, MODIFY_TIME, LocalDateTime.class, now); |
32 | 32 | this.strictInsertFill(metaObject, ENABLE_FLAG, Integer.class, Constant.ENABLE_TEN); |
33 | - UserDetails loginUser = SecurityUtils.getUserDetails(); | |
34 | - if (null == loginUser) { | |
35 | - return; | |
36 | - } | |
33 | + try { | |
34 | + UserDetails loginUser = SecurityUtils.getUserDetails(); | |
35 | + | |
36 | + this.strictInsertFill(metaObject, CREATE_BY, String.class, loginUser.getUsername()); | |
37 | + | |
38 | + this.strictInsertFill(metaObject, MODIFY_BY, String.class, loginUser.getUsername()); | |
39 | + }catch (Exception e) { | |
40 | + this.strictInsertFill(metaObject, CREATE_BY, String.class, "system"); | |
37 | 41 | |
38 | - this.strictInsertFill(metaObject, CREATE_BY, String.class, loginUser.getUsername()); | |
42 | + this.strictInsertFill(metaObject, MODIFY_BY, String.class, "system"); | |
43 | + } | |
39 | 44 | |
40 | - this.strictInsertFill(metaObject, MODIFY_BY, String.class, loginUser.getUsername()); | |
41 | 45 | |
42 | 46 | } |
43 | 47 | |
... | ... | @@ -46,10 +50,16 @@ public class AdminMetaObjectHandler implements MetaObjectHandler { |
46 | 50 | |
47 | 51 | this.strictUpdateFill(metaObject, MODIFY_TIME, LocalDateTime.class, LocalDateTime.now()); |
48 | 52 | |
49 | - UserDetails loginUser = SecurityUtils.getUserDetails(); | |
50 | - if (null == loginUser) { | |
51 | - return; | |
53 | + | |
54 | + try { | |
55 | + UserDetails loginUser = SecurityUtils.getUserDetails(); | |
56 | + if (null == loginUser) { | |
57 | + return; | |
58 | + } | |
59 | + this.strictUpdateFill(metaObject, MODIFY_BY, String.class, loginUser.getUsername()); | |
60 | + }catch (Exception e) { | |
61 | + this.strictUpdateFill(metaObject, MODIFY_BY, String.class, "system"); | |
52 | 62 | } |
53 | - this.strictUpdateFill(metaObject, MODIFY_BY, String.class, loginUser.getUsername()); | |
63 | + | |
54 | 64 | } |
55 | 65 | } | ... | ... |
src/main/java/com/order/erp/controller/DeptController.java
1 | 1 | package com.order.erp.controller; |
2 | 2 | |
3 | +import com.order.erp.common.annotation.AnonymousAccess; | |
3 | 4 | import com.order.erp.common.constant.ServerResult; |
4 | 5 | import com.order.erp.domain.vo.admin.AdminDeptQueryVO; |
5 | 6 | import com.order.erp.domain.vo.admin.AdminDeptVO; |
... | ... | @@ -28,7 +29,7 @@ public class DeptController { |
28 | 29 | @Log("查询部门") |
29 | 30 | @ApiOperation("查询部门") |
30 | 31 | @PostMapping(value = "/list_by_page") |
31 | - @PreAuthorize("@el.check('user:list','dept:list')") | |
32 | + @AnonymousAccess | |
32 | 33 | public ServerResult listByPage(@RequestBody @Validated AdminDeptQueryVO queryVO) { |
33 | 34 | return deptService.list(queryVO); |
34 | 35 | } |
... | ... | @@ -36,7 +37,7 @@ public class DeptController { |
36 | 37 | @Log("新增部门") |
37 | 38 | @ApiOperation("新增部门") |
38 | 39 | @PostMapping("/add") |
39 | - @PreAuthorize("@el.check('dept:add')") | |
40 | + @AnonymousAccess | |
40 | 41 | public ServerResult add(@RequestBody @Validated AdminDeptVO deptVO) { |
41 | 42 | return deptService.add(deptVO); |
42 | 43 | } |
... | ... | @@ -44,7 +45,7 @@ public class DeptController { |
44 | 45 | @Log("修改部门") |
45 | 46 | @ApiOperation("修改部门") |
46 | 47 | @PutMapping |
47 | - @PreAuthorize("@el.check('dept:edit')") | |
48 | + @AnonymousAccess | |
48 | 49 | public ServerResult edit(@RequestBody @Validated AdminDeptVO deptVO) { |
49 | 50 | return deptService.edit(deptVO); |
50 | 51 | } |
... | ... | @@ -52,7 +53,7 @@ public class DeptController { |
52 | 53 | @Log("删除部门") |
53 | 54 | @ApiOperation("删除部门") |
54 | 55 | @DeleteMapping |
55 | - @PreAuthorize("@el.check('dept:del')") | |
56 | + @AnonymousAccess | |
56 | 57 | public ServerResult delete(@RequestBody @Validated AdminDeptQueryVO queryVO) { |
57 | 58 | return deptService.deleteById(queryVO); |
58 | 59 | } | ... | ... |
src/main/java/com/order/erp/controller/DictionaryController.java
1 | 1 | package com.order.erp.controller; |
2 | 2 | |
3 | +import com.order.erp.common.annotation.AnonymousAccess; | |
3 | 4 | import com.order.erp.common.constant.ServerResult; |
4 | 5 | import com.order.erp.domain.vo.admin.DictionaryQueryVO; |
5 | 6 | import com.order.erp.domain.vo.admin.DictionaryVO; |
... | ... | @@ -31,7 +32,7 @@ public class DictionaryController { |
31 | 32 | @Log("查询字典列表") |
32 | 33 | @ApiOperation("查询字典列表") |
33 | 34 | @PostMapping(value = "/list_by_page") |
34 | - @PreAuthorize("@el.check('user:list','dept:list')") | |
35 | + @AnonymousAccess | |
35 | 36 | public ServerResult listByPage(@RequestBody @Validated DictionaryQueryVO queryVO) { |
36 | 37 | return dictionaryService.listByPage(queryVO); |
37 | 38 | } |
... | ... | @@ -39,7 +40,7 @@ public class DictionaryController { |
39 | 40 | @Log("获取所有字典") |
40 | 41 | @ApiOperation("获取所有字典") |
41 | 42 | @PostMapping(value = "/get_all") |
42 | - @PreAuthorize("@el.check('user:list','dept:list')") | |
43 | + @AnonymousAccess | |
43 | 44 | public ServerResult getAll(@RequestBody @Validated DictionaryQueryVO queryVO) { |
44 | 45 | return dictionaryService.getAll(queryVO); |
45 | 46 | } |
... | ... | @@ -47,7 +48,7 @@ public class DictionaryController { |
47 | 48 | @Log("新增字典") |
48 | 49 | @ApiOperation("新增字典") |
49 | 50 | @PostMapping("/add") |
50 | - @PreAuthorize("@el.check('dept:add')") | |
51 | + @AnonymousAccess | |
51 | 52 | public ServerResult add(@RequestBody @Validated DictionaryVO dictionaryVO) { |
52 | 53 | return dictionaryService.add(dictionaryVO); |
53 | 54 | } |
... | ... | @@ -55,7 +56,7 @@ public class DictionaryController { |
55 | 56 | @Log("修改字典") |
56 | 57 | @ApiOperation("修改字典") |
57 | 58 | @PostMapping("/edit") |
58 | - @PreAuthorize("@el.check('dept:edit')") | |
59 | + @AnonymousAccess | |
59 | 60 | public ServerResult edit(@RequestBody @Validated DictionaryVO dictionaryVO) { |
60 | 61 | return dictionaryService.edit(dictionaryVO); |
61 | 62 | } |
... | ... | @@ -63,7 +64,7 @@ public class DictionaryController { |
63 | 64 | @Log("删除字典") |
64 | 65 | @ApiOperation("删除字典") |
65 | 66 | @PostMapping("/delete") |
66 | - @PreAuthorize("@el.check('dept:del')") | |
67 | + @AnonymousAccess | |
67 | 68 | public ServerResult delete(@RequestBody @Validated DictionaryQueryVO queryVO) { |
68 | 69 | return dictionaryService.deleteById(queryVO); |
69 | 70 | } | ... | ... |
src/main/java/com/order/erp/controller/JobController.java
1 | 1 | package com.order.erp.controller; |
2 | 2 | |
3 | +import com.order.erp.common.annotation.AnonymousAccess; | |
3 | 4 | import com.order.erp.common.constant.ServerResult; |
4 | 5 | import com.order.erp.domain.vo.admin.AdminJobQueryVO; |
5 | 6 | import com.order.erp.domain.vo.admin.AdminJobVO; |
... | ... | @@ -30,7 +31,7 @@ public class JobController { |
30 | 31 | @Log("查询岗位") |
31 | 32 | @ApiOperation("查询岗位") |
32 | 33 | @PostMapping(value = "/list_by_page") |
33 | - @PreAuthorize("@el.check('job:list','user:list')") | |
34 | + @AnonymousAccess | |
34 | 35 | public ServerResult listByPage(@RequestBody @Validated AdminJobQueryVO queryVO) { |
35 | 36 | return jobService.list(queryVO); |
36 | 37 | } |
... | ... | @@ -38,7 +39,7 @@ public class JobController { |
38 | 39 | @Log("新增岗位") |
39 | 40 | @ApiOperation("新增岗位") |
40 | 41 | @PostMapping(value = "/add") |
41 | - @PreAuthorize("@el.check('job:add')") | |
42 | + @AnonymousAccess | |
42 | 43 | public ServerResult add(@RequestBody @Validated AdminJobVO jobVO) { |
43 | 44 | return jobService.add(jobVO); |
44 | 45 | } |
... | ... | @@ -46,7 +47,7 @@ public class JobController { |
46 | 47 | @Log("修改岗位") |
47 | 48 | @ApiOperation("修改岗位") |
48 | 49 | @PostMapping(value = "/edit") |
49 | - @PreAuthorize("@el.check('job:edit')") | |
50 | + @AnonymousAccess | |
50 | 51 | public ServerResult edit(@RequestBody @Validated AdminJobVO jobVO) { |
51 | 52 | return jobService.edit(jobVO); |
52 | 53 | } |
... | ... | @@ -54,7 +55,7 @@ public class JobController { |
54 | 55 | @Log("删除岗位") |
55 | 56 | @ApiOperation("删除岗位") |
56 | 57 | @PostMapping(value = "/delete") |
57 | - @PreAuthorize("@el.check('job:del')") | |
58 | + @AnonymousAccess | |
58 | 59 | public ServerResult delete(@RequestBody @Validated AdminJobQueryVO queryVO) { |
59 | 60 | return jobService.deleteById(queryVO); |
60 | 61 | } | ... | ... |
src/main/java/com/order/erp/controller/MenuController.java
1 | 1 | package com.order.erp.controller; |
2 | 2 | |
3 | +import com.order.erp.common.annotation.AnonymousAccess; | |
3 | 4 | import com.order.erp.common.constant.ServerResult; |
4 | 5 | import com.order.erp.domain.vo.admin.AdminMenuQueryVO; |
5 | 6 | import com.order.erp.domain.vo.admin.AdminMenuVO; |
... | ... | @@ -30,13 +31,14 @@ public class MenuController { |
30 | 31 | |
31 | 32 | @ApiOperation("获取前端所需菜单") |
32 | 33 | @PostMapping(value = "/build") |
34 | + @AnonymousAccess | |
33 | 35 | public ServerResult buildMenus() { |
34 | 36 | return ServerResult.success(); |
35 | 37 | } |
36 | 38 | |
37 | 39 | @ApiOperation("返回全部的菜单") |
38 | 40 | @PostMapping(value = "/tree") |
39 | - @PreAuthorize("@el.check('menu:list','roles:list')") | |
41 | + @AnonymousAccess | |
40 | 42 | public ServerResult getMenuTree() { |
41 | 43 | return ServerResult.success(); |
42 | 44 | } |
... | ... | @@ -44,7 +46,7 @@ public class MenuController { |
44 | 46 | @Log("查询菜单") |
45 | 47 | @ApiOperation("查询菜单") |
46 | 48 | @PostMapping(value = "/all") |
47 | - @PreAuthorize("@el.check('menu:list')") | |
49 | + @AnonymousAccess | |
48 | 50 | public ServerResult all(@RequestBody @Validated AdminMenuQueryVO queryVO) { |
49 | 51 | return menuService.all(queryVO); |
50 | 52 | } |
... | ... | @@ -52,7 +54,7 @@ public class MenuController { |
52 | 54 | @Log("新增菜单") |
53 | 55 | @ApiOperation("新增菜单") |
54 | 56 | @PostMapping(value = "/add") |
55 | - @PreAuthorize("@el.check('menu:add')") | |
57 | + @AnonymousAccess | |
56 | 58 | public ServerResult add(@RequestBody @Validated AdminMenuVO menuVO) { |
57 | 59 | return menuService.add(menuVO); |
58 | 60 | } |
... | ... | @@ -60,7 +62,7 @@ public class MenuController { |
60 | 62 | @Log("修改菜单") |
61 | 63 | @ApiOperation("修改菜单") |
62 | 64 | @PostMapping(value = "/edit") |
63 | - @PreAuthorize("@el.check('menu:edit')") | |
65 | + @AnonymousAccess | |
64 | 66 | public ServerResult edit(@RequestBody @Validated AdminMenuVO menuVO) { |
65 | 67 | return menuService.edit(menuVO); |
66 | 68 | } |
... | ... | @@ -68,7 +70,7 @@ public class MenuController { |
68 | 70 | @Log("删除菜单") |
69 | 71 | @ApiOperation("删除菜单") |
70 | 72 | @PostMapping(value = "/delete") |
71 | - @PreAuthorize("@el.check('menu:del')") | |
73 | + @AnonymousAccess | |
72 | 74 | public ServerResult delete(@RequestBody @Validated AdminMenuQueryVO queryVO) { |
73 | 75 | return menuService.deleteById(queryVO); |
74 | 76 | } | ... | ... |
src/main/java/com/order/erp/controller/OrderAuditLogController.java
1 | 1 | package com.order.erp.controller; |
2 | 2 | |
3 | +import com.order.erp.common.annotation.AnonymousAccess; | |
3 | 4 | import com.order.erp.common.constant.ServerResult; |
4 | 5 | import com.order.erp.domain.vo.order.OrderAuditLogQueryVO; |
5 | 6 | import com.order.erp.service.order.OrderAuditLogService; |
... | ... | @@ -33,6 +34,7 @@ public class OrderAuditLogController { |
33 | 34 | * @return 查询结果 |
34 | 35 | */ |
35 | 36 | @PostMapping("/list") |
37 | + @AnonymousAccess | |
36 | 38 | public ServerResult list(@RequestBody @Validated OrderAuditLogQueryVO orderAuditLogQueryVO) { |
37 | 39 | return orderAuditLogService.list(orderAuditLogQueryVO); |
38 | 40 | } |
... | ... | @@ -44,6 +46,7 @@ public class OrderAuditLogController { |
44 | 46 | * @return 单条数据 |
45 | 47 | */ |
46 | 48 | @PostMapping("/query_by_id") |
49 | + @AnonymousAccess | |
47 | 50 | public ServerResult queryById(@RequestBody OrderAuditLogQueryVO orderAuditLogQueryVO) { |
48 | 51 | return orderAuditLogService.queryById(orderAuditLogQueryVO); |
49 | 52 | } | ... | ... |
src/main/java/com/order/erp/controller/OrderController.java
... | ... | @@ -2,7 +2,11 @@ package com.order.erp.controller; |
2 | 2 | |
3 | 3 | import com.order.erp.common.annotation.AnonymousAccess; |
4 | 4 | import com.order.erp.common.constant.ServerResult; |
5 | -import com.order.erp.domain.vo.order.*; | |
5 | +import com.order.erp.common.excel4j.exceptions.Excel4JException; | |
6 | +import com.order.erp.domain.vo.order.OrderAddVO; | |
7 | +import com.order.erp.domain.vo.order.OrderBaseInfoQueryVO; | |
8 | +import com.order.erp.domain.vo.order.OrderBaseInfoVO; | |
9 | +import com.order.erp.domain.vo.order.OrderUnlockFieldApplyVO; | |
6 | 10 | import com.order.erp.service.order.OrderBaseInfoService; |
7 | 11 | import org.springframework.validation.annotation.Validated; |
8 | 12 | import org.springframework.web.bind.annotation.PostMapping; |
... | ... | @@ -11,6 +15,8 @@ import org.springframework.web.bind.annotation.RequestMapping; |
11 | 15 | import org.springframework.web.bind.annotation.RestController; |
12 | 16 | |
13 | 17 | import javax.annotation.Resource; |
18 | +import javax.servlet.http.HttpServletResponse; | |
19 | +import java.io.IOException; | |
14 | 20 | |
15 | 21 | /** |
16 | 22 | * 订单基础信息表(OrderBaseInfo)表控制层 |
... | ... | @@ -40,6 +46,18 @@ public class OrderController { |
40 | 46 | } |
41 | 47 | |
42 | 48 | /** |
49 | + * 导出订单 | |
50 | + * | |
51 | + * @param orderBaseInfoQueryVO 查询条件 | |
52 | + * @return 查询结果 | |
53 | + */ | |
54 | + @PostMapping("/export") | |
55 | + @AnonymousAccess | |
56 | + public ServerResult export(HttpServletResponse response, @RequestBody @Validated OrderBaseInfoQueryVO orderBaseInfoQueryVO) throws IOException, Excel4JException { | |
57 | + return orderBaseInfoService.export(response, orderBaseInfoQueryVO); | |
58 | + } | |
59 | + | |
60 | + /** | |
43 | 61 | * 通过主键查询单条数据 |
44 | 62 | * |
45 | 63 | * @param orderBaseInfoQueryVO 查询条件 | ... | ... |
src/main/java/com/order/erp/controller/OrderFieldLockApplyController.java
1 | 1 | package com.order.erp.controller; |
2 | 2 | |
3 | +import com.order.erp.common.annotation.AnonymousAccess; | |
3 | 4 | import com.order.erp.common.constant.ServerResult; |
4 | 5 | import com.order.erp.domain.vo.order.OrderFieldLockApplyQueryVO; |
5 | 6 | import com.order.erp.domain.vo.order.OrderFieldLockApplyVO; |
... | ... | @@ -34,6 +35,7 @@ public class OrderFieldLockApplyController { |
34 | 35 | * @return 查询结果 |
35 | 36 | */ |
36 | 37 | @PostMapping("/list") |
38 | + @AnonymousAccess | |
37 | 39 | public ServerResult list(@RequestBody @Validated OrderFieldLockApplyQueryVO orderFieldLockApplyQueryVO) { |
38 | 40 | return orderFieldLockApplyService.list(orderFieldLockApplyQueryVO); |
39 | 41 | } |
... | ... | @@ -45,6 +47,7 @@ public class OrderFieldLockApplyController { |
45 | 47 | * @return 单条数据 |
46 | 48 | */ |
47 | 49 | @PostMapping("/query_by_id") |
50 | + @AnonymousAccess | |
48 | 51 | public ServerResult queryById(@RequestBody OrderFieldLockApplyQueryVO orderFieldLockApplyQueryVO) { |
49 | 52 | return orderFieldLockApplyService.queryById(orderFieldLockApplyQueryVO); |
50 | 53 | } |
... | ... | @@ -56,6 +59,7 @@ public class OrderFieldLockApplyController { |
56 | 59 | * @return 新增结果 |
57 | 60 | */ |
58 | 61 | @PostMapping("/add") |
62 | + @AnonymousAccess | |
59 | 63 | public ServerResult add(@RequestBody OrderFieldLockApplyVO orderFieldLockApplyVO) { |
60 | 64 | return orderFieldLockApplyService.add(orderFieldLockApplyVO); |
61 | 65 | } |
... | ... | @@ -67,6 +71,7 @@ public class OrderFieldLockApplyController { |
67 | 71 | * @return 编辑结果 |
68 | 72 | */ |
69 | 73 | @PostMapping("/edit") |
74 | + @AnonymousAccess | |
70 | 75 | public ServerResult edit(@RequestBody OrderFieldLockApplyVO orderFieldLockApplyVO) { |
71 | 76 | return orderFieldLockApplyService.edit(orderFieldLockApplyVO); |
72 | 77 | } |
... | ... | @@ -78,6 +83,7 @@ public class OrderFieldLockApplyController { |
78 | 83 | * @return 删除是否成功 |
79 | 84 | */ |
80 | 85 | @PostMapping("/delete_by_id") |
86 | + @AnonymousAccess | |
81 | 87 | public ServerResult deleteById(@RequestBody OrderFieldLockApplyQueryVO orderFieldLockApplyQueryVO) { |
82 | 88 | return orderFieldLockApplyService.deleteById(orderFieldLockApplyQueryVO); |
83 | 89 | } | ... | ... |
src/main/java/com/order/erp/controller/RoleController.java
1 | 1 | package com.order.erp.controller; |
2 | 2 | |
3 | +import com.order.erp.common.annotation.AnonymousAccess; | |
3 | 4 | import com.order.erp.common.constant.ServerResult; |
4 | 5 | import com.order.erp.domain.vo.admin.AdminAuthRoleVO; |
5 | 6 | import com.order.erp.domain.vo.admin.AdminRoleQueryVO; |
... | ... | @@ -37,14 +38,14 @@ public class RoleController { |
37 | 38 | |
38 | 39 | @ApiOperation("获取单个role") |
39 | 40 | @PostMapping(value = "/detail") |
40 | - @PreAuthorize("@el.check('roles:list')") | |
41 | + @AnonymousAccess | |
41 | 42 | public ServerResult detail(@RequestBody @Validated AdminRoleQueryVO queryVO) { |
42 | 43 | return ServerResult.success(roleService.getById(queryVO.getId())); |
43 | 44 | } |
44 | 45 | |
45 | 46 | @ApiOperation("返回全部的角色") |
46 | 47 | @PostMapping(value = "/all") |
47 | - @PreAuthorize("@el.check('roles:list','user:add','user:edit')") | |
48 | + @AnonymousAccess | |
48 | 49 | public ServerResult getAll(@RequestBody @Validated AdminRoleQueryVO queryVO) { |
49 | 50 | return roleService.listByLevel(queryVO.getLevel()); |
50 | 51 | } |
... | ... | @@ -52,7 +53,7 @@ public class RoleController { |
52 | 53 | @Log("查询角色") |
53 | 54 | @ApiOperation("查询角色") |
54 | 55 | @PostMapping(value = "/list_by_page") |
55 | - @PreAuthorize("@el.check('roles:list')") | |
56 | + @AnonymousAccess | |
56 | 57 | public ServerResult listByPage(@RequestBody @Validated AdminRoleQueryVO queryVO) { |
57 | 58 | return roleService.listByPage(queryVO); |
58 | 59 | } |
... | ... | @@ -60,7 +61,7 @@ public class RoleController { |
60 | 61 | @Log("新增角色") |
61 | 62 | @ApiOperation("新增角色") |
62 | 63 | @PostMapping(value = "/add") |
63 | - @PreAuthorize("@el.check('roles:add')") | |
64 | + @AnonymousAccess | |
64 | 65 | public ServerResult add(@RequestBody @Validated AdminRoleVO roleVO) { |
65 | 66 | return roleService.add(roleVO); |
66 | 67 | } |
... | ... | @@ -68,7 +69,7 @@ public class RoleController { |
68 | 69 | @Log("修改角色") |
69 | 70 | @ApiOperation("修改角色") |
70 | 71 | @PostMapping(value = "/edit") |
71 | - @PreAuthorize("@el.check('roles:edit')") | |
72 | + @AnonymousAccess | |
72 | 73 | public ServerResult edit(@RequestBody @Validated AdminRoleVO roleVO) { |
73 | 74 | return roleService.edit(roleVO); |
74 | 75 | } |
... | ... | @@ -76,7 +77,7 @@ public class RoleController { |
76 | 77 | @Log("授权角色菜单") |
77 | 78 | @ApiOperation("授权角色菜单") |
78 | 79 | @PostMapping(value = "/auth_menu") |
79 | - @PreAuthorize("@el.check('roles:edit')") | |
80 | + @AnonymousAccess | |
80 | 81 | public ServerResult authMenu(@RequestBody @Validated AdminAuthRoleVO roleVO) { |
81 | 82 | return roleService.authMenu(roleVO); |
82 | 83 | } |
... | ... | @@ -84,7 +85,7 @@ public class RoleController { |
84 | 85 | @Log("删除角色") |
85 | 86 | @ApiOperation("删除角色") |
86 | 87 | @PostMapping(value = "/delete") |
87 | - @PreAuthorize("@el.check('roles:del')") | |
88 | + @AnonymousAccess | |
88 | 89 | public ServerResult delete(@RequestBody @Validated AdminRoleQueryVO queryVO) { |
89 | 90 | return roleService.deleteById(queryVO); |
90 | 91 | } | ... | ... |
src/main/java/com/order/erp/controller/SysLogController.java
1 | 1 | package com.order.erp.controller; |
2 | 2 | |
3 | +import com.order.erp.common.annotation.AnonymousAccess; | |
3 | 4 | import com.order.erp.common.constant.ServerResult; |
4 | 5 | import com.order.erp.domain.vo.SysLogQueryVO; |
5 | 6 | import com.order.erp.domain.vo.SysLogVO; |
... | ... | @@ -34,6 +35,7 @@ public class SysLogController { |
34 | 35 | * @return 查询结果 |
35 | 36 | */ |
36 | 37 | @PostMapping("/list") |
38 | + @AnonymousAccess | |
37 | 39 | public ServerResult list(@RequestBody @Validated SysLogQueryVO sysLogQueryVO) { |
38 | 40 | return sysLogService.list(sysLogQueryVO); |
39 | 41 | } |
... | ... | @@ -45,6 +47,7 @@ public class SysLogController { |
45 | 47 | * @return 单条数据 |
46 | 48 | */ |
47 | 49 | @PostMapping("/query_by_id") |
50 | + @AnonymousAccess | |
48 | 51 | public ServerResult queryById(@RequestBody SysLogQueryVO sysLogQueryVO) { |
49 | 52 | return sysLogService.queryById(sysLogQueryVO); |
50 | 53 | } |
... | ... | @@ -56,6 +59,7 @@ public class SysLogController { |
56 | 59 | * @return 新增结果 |
57 | 60 | */ |
58 | 61 | @PostMapping("/add") |
62 | + @AnonymousAccess | |
59 | 63 | public ServerResult add(@RequestBody SysLogVO sysLogVO) { |
60 | 64 | return sysLogService.add(sysLogVO); |
61 | 65 | } |
... | ... | @@ -67,6 +71,7 @@ public class SysLogController { |
67 | 71 | * @return 编辑结果 |
68 | 72 | */ |
69 | 73 | @PostMapping("/edit") |
74 | + @AnonymousAccess | |
70 | 75 | public ServerResult edit(@RequestBody SysLogVO sysLogVO) { |
71 | 76 | return sysLogService.edit(sysLogVO); |
72 | 77 | } |
... | ... | @@ -78,6 +83,7 @@ public class SysLogController { |
78 | 83 | * @return 删除是否成功 |
79 | 84 | */ |
80 | 85 | @PostMapping("/delete_by_id") |
86 | + @AnonymousAccess | |
81 | 87 | public ServerResult deleteById(@RequestBody SysLogQueryVO sysLogQueryVO) { |
82 | 88 | return sysLogService.deleteById(sysLogQueryVO); |
83 | 89 | } | ... | ... |
src/main/java/com/order/erp/controller/UserController.java
1 | 1 | package com.order.erp.controller; |
2 | 2 | |
3 | +import com.order.erp.common.annotation.AnonymousAccess; | |
3 | 4 | import com.order.erp.common.constant.ServerResult; |
4 | 5 | import com.order.erp.config.DataScope; |
5 | 6 | import com.order.erp.domain.vo.admin.AdminAuthUserVO; |
6 | 7 | import com.order.erp.domain.vo.admin.AdminUserQueryVO; |
7 | 8 | import com.order.erp.domain.vo.admin.AdminUserVO; |
9 | +import com.order.erp.domain.vo.admin.UpdatePwdVO; | |
8 | 10 | import com.order.erp.log.Log; |
9 | 11 | import com.order.erp.service.admin.AdminUserService; |
10 | 12 | import io.swagger.annotations.Api; |
... | ... | @@ -37,7 +39,7 @@ public class UserController { |
37 | 39 | @Log("查询用户") |
38 | 40 | @ApiOperation("查询用户") |
39 | 41 | @PostMapping(value = "list_by_page") |
40 | - @PreAuthorize("@el.check('user:list')") | |
42 | + @AnonymousAccess | |
41 | 43 | public ServerResult listByPage(@RequestBody @Validated AdminUserQueryVO queryVO) { |
42 | 44 | return userService.list(queryVO); |
43 | 45 | } |
... | ... | @@ -45,7 +47,7 @@ public class UserController { |
45 | 47 | @Log("授权角色") |
46 | 48 | @ApiOperation("授权角色") |
47 | 49 | @PostMapping(value = "/auth_role") |
48 | - @PreAuthorize("@el.check('user:add')") | |
50 | + @AnonymousAccess | |
49 | 51 | public ServerResult authRole(@RequestBody @Validated AdminAuthUserVO userVO) { |
50 | 52 | return userService.authRole(userVO); |
51 | 53 | } |
... | ... | @@ -53,7 +55,7 @@ public class UserController { |
53 | 55 | @Log("新增用户") |
54 | 56 | @ApiOperation("新增用户") |
55 | 57 | @PostMapping(value = "/add") |
56 | - @PreAuthorize("@el.check('user:add')") | |
58 | + @AnonymousAccess | |
57 | 59 | public ServerResult add(@RequestBody @Validated AdminUserVO userVO) { |
58 | 60 | return userService.add(userVO); |
59 | 61 | } |
... | ... | @@ -61,14 +63,14 @@ public class UserController { |
61 | 63 | @Log("修改用户") |
62 | 64 | @ApiOperation("修改用户") |
63 | 65 | @PostMapping(value = "/edit") |
64 | - @PreAuthorize("@el.check('user:edit')") | |
66 | + @AnonymousAccess | |
65 | 67 | public ServerResult edit(@RequestBody @Validated AdminUserVO userVO) { |
66 | 68 | return userService.edit(userVO); |
67 | 69 | } |
68 | 70 | |
69 | 71 | @Log("修改用户:个人中心") |
70 | 72 | @ApiOperation("修改用户:个人中心") |
71 | - @PostMapping(value = "/center") | |
73 | + @AnonymousAccess | |
72 | 74 | public ServerResult center(@RequestBody @Validated AdminUserVO userVO) { |
73 | 75 | return ServerResult.success(); |
74 | 76 | } |
... | ... | @@ -76,26 +78,27 @@ public class UserController { |
76 | 78 | @Log("删除用户") |
77 | 79 | @ApiOperation("删除用户") |
78 | 80 | @PostMapping(value = "/delete") |
79 | - @PreAuthorize("@el.check('user:del')") | |
81 | + @AnonymousAccess | |
80 | 82 | public ServerResult delete(@RequestBody @Validated AdminUserQueryVO queryVO) { |
81 | 83 | return userService.deleteById(queryVO); |
82 | 84 | } |
83 | 85 | |
86 | + @Log("修改密码") | |
84 | 87 | @ApiOperation("修改密码") |
85 | - @PostMapping(value = "/updatePass") | |
86 | - public ServerResult updatePass(@RequestBody @Validated AdminUserQueryVO queryVO) { | |
87 | - return ServerResult.success(); | |
88 | + @AnonymousAccess | |
89 | + public ServerResult updatePass(@RequestBody @Validated UpdatePwdVO pwdVO) { | |
90 | + return userService.updatePass(pwdVO); | |
88 | 91 | } |
89 | 92 | |
90 | 93 | @ApiOperation("修改头像") |
91 | - @PostMapping(value = "/updateAvatar") | |
94 | + @AnonymousAccess | |
92 | 95 | public ServerResult updateAvatar(@RequestParam MultipartFile file) { |
93 | 96 | return ServerResult.success(); |
94 | 97 | } |
95 | 98 | |
96 | 99 | @Log("修改邮箱") |
97 | 100 | @ApiOperation("修改邮箱") |
98 | - @PostMapping(value = "/updateEmail") | |
101 | + @AnonymousAccess | |
99 | 102 | public ServerResult updateEmail(@RequestBody @Validated AdminUserQueryVO queryVO) { |
100 | 103 | return ServerResult.success(); |
101 | 104 | } | ... | ... |
src/main/java/com/order/erp/domain/RoleEnum.java
0 → 100644
1 | +package com.order.erp.domain; | |
2 | + | |
3 | +import lombok.AllArgsConstructor; | |
4 | +import lombok.Getter; | |
5 | + | |
6 | +/** | |
7 | + * @author: xms | |
8 | + * @description: TODO | |
9 | + * @date: 2023/9/13 18:05 | |
10 | + * @version: 1.0 | |
11 | + */ | |
12 | +@Getter | |
13 | +@AllArgsConstructor | |
14 | +public enum RoleEnum { | |
15 | + | |
16 | + ADMIN("admin", 1L, "超级管理员"), | |
17 | + BUSINESS_USER("business_user", 2L, "业务员"), | |
18 | + TRACKER_USER("tracker_user", 3L, "跟单员"), | |
19 | + INSPECT_USER("inspect_user", 4L, "质检员"), | |
20 | + ; | |
21 | + private String code; | |
22 | + | |
23 | + private Long id; | |
24 | + | |
25 | + private String name; | |
26 | + | |
27 | + | |
28 | + /** | |
29 | + * | |
30 | + * @param id | |
31 | + * @return | |
32 | + */ | |
33 | + public static String getCodeById(Long id) { | |
34 | + RoleEnum[] roleEnums = RoleEnum.values(); | |
35 | + for (RoleEnum roleEnum : roleEnums) { | |
36 | + if (roleEnum.id.equals(id)) { | |
37 | + return roleEnum.getCode(); | |
38 | + } | |
39 | + } | |
40 | + return null; | |
41 | + } | |
42 | + | |
43 | + /** | |
44 | + * | |
45 | + * @param id | |
46 | + * @return | |
47 | + */ | |
48 | + public static String getNameById(Long id) { | |
49 | + RoleEnum[] roleEnums = RoleEnum.values(); | |
50 | + for (RoleEnum roleEnum : roleEnums) { | |
51 | + if (roleEnum.id.equals(id)) { | |
52 | + return roleEnum.getName(); | |
53 | + } | |
54 | + } | |
55 | + return null; | |
56 | + } | |
57 | +} | ... | ... |
src/main/java/com/order/erp/domain/excel/OrderExcelVO.java
0 → 100644
1 | +package com.order.erp.domain.excel; | |
2 | + | |
3 | +import com.order.erp.common.excel4j.annotation.ExcelField; | |
4 | +import lombok.Data; | |
5 | + | |
6 | +import java.io.Serializable; | |
7 | + | |
8 | +/** | |
9 | + * @author: xms | |
10 | + * @description: 订单 | |
11 | + * @date: 2023/1/11 16:01 | |
12 | + * @version: 1.0 | |
13 | + */ | |
14 | +@Data | |
15 | +public class OrderExcelVO implements Serializable { | |
16 | + | |
17 | + | |
18 | + /** | |
19 | + * 客户编码 | |
20 | + */ | |
21 | + @ExcelField(title = "客户编码", order = 1) | |
22 | + private String customerCode; | |
23 | + /** | |
24 | + * 项目号 | |
25 | + */ | |
26 | + @ExcelField(title = "项目号", order = 2) | |
27 | + private String projectNo; | |
28 | + /** | |
29 | + * 生产科 | |
30 | + */ | |
31 | + @ExcelField(title = "生产科", order = 3) | |
32 | + private String productionDepartment; | |
33 | + /** | |
34 | + * 内部编号 | |
35 | + */ | |
36 | + @ExcelField(title = "内部编号", order = 4) | |
37 | + private String innerNo; | |
38 | + /** | |
39 | + * 客户po号 | |
40 | + */ | |
41 | + @ExcelField(title = "客户po号", order = 5) | |
42 | + private String customerPo; | |
43 | + /** | |
44 | + * 客户STYLE# | |
45 | + */ | |
46 | + @ExcelField(title = "客户STYLE#", order = 6) | |
47 | + private String customerStyle; | |
48 | + /** | |
49 | + * Modelo(REFERENCE) | |
50 | + */ | |
51 | + @ExcelField(title = "Modelo(REFERENCE)", order = 7) | |
52 | + private String modeleLo; | |
53 | + /** | |
54 | + * COLLECTION (style description) | |
55 | + */ | |
56 | + @ExcelField(title = "COLLECTION (style description)", order = 8) | |
57 | + private String collection; | |
58 | + /** | |
59 | + * PO COLOR | |
60 | + */ | |
61 | + @ExcelField(title = "PO COLOR", order = 9) | |
62 | + private String poColor; | |
63 | + /** | |
64 | + * 颜色中文 | |
65 | + */ | |
66 | + @ExcelField(title = "颜色中文", order = 10) | |
67 | + private String cnColor; | |
68 | + /** | |
69 | + * pic图片地址 | |
70 | + */ | |
71 | + @ExcelField(title = "pic图片地址", order = 11) | |
72 | + private String picUrl; | |
73 | + /** | |
74 | + * 生产要求 | |
75 | + */ | |
76 | + @ExcelField(title = "生产要求", order = 12) | |
77 | + private String productionComment; | |
78 | + /** | |
79 | + * 数量 | |
80 | + */ | |
81 | + @ExcelField(title = "数量", order = 13) | |
82 | + private Integer orderCount; | |
83 | + /** | |
84 | + * 订单成分 | |
85 | + */ | |
86 | + @ExcelField(title = "订单成分", order = 14) | |
87 | + private String orderComposition; | |
88 | + /** | |
89 | + * 款式类型 | |
90 | + */ | |
91 | + @ExcelField(title = "款式类型", order = 15) | |
92 | + private String productStyle; | |
93 | + /** | |
94 | + * 生成科拖货时间 | |
95 | + */ | |
96 | + @ExcelField(title = "生成科拖货时间", order = 16) | |
97 | + private String productionDepartmentConsignTime; | |
98 | + /** | |
99 | + * 订单上HOD时间 | |
100 | + */ | |
101 | + @ExcelField(title = "订单上HOD时间", order = 17) | |
102 | + private String orderHodTime; | |
103 | + /** | |
104 | + * 出库类型 | |
105 | + */ | |
106 | + @ExcelField(title = "出库类型", order = 18) | |
107 | + private String outboundType; | |
108 | + /** | |
109 | + * 包装类型 | |
110 | + */ | |
111 | + @ExcelField(title = "包装类型", order = 19) | |
112 | + private String packetType; | |
113 | + | |
114 | + /** | |
115 | + * 客户单价$ | |
116 | + */ | |
117 | + @ExcelField(title = "客户单价$", order = 20) | |
118 | + private Double customerPrice; | |
119 | + | |
120 | + /** | |
121 | + * 客户总价$ | |
122 | + */ | |
123 | + @ExcelField(title = "客户总价$", order = 21) | |
124 | + private Double customerTotalPrice; | |
125 | + /** | |
126 | + * 生成科单价¥ | |
127 | + */ | |
128 | + @ExcelField(title = "生成科单价¥", order = 22) | |
129 | + private Double productionDepartmentPrice; | |
130 | + /** | |
131 | + * 生成科总价¥ | |
132 | + */ | |
133 | + @ExcelField(title = "生成科总价¥", order = 23) | |
134 | + private Double productionDepartmentTotalPrice; | |
135 | + /** | |
136 | + * 包装费用¥ | |
137 | + */ | |
138 | + @ExcelField(title = "包装费用¥", order = 24) | |
139 | + private Double packetPrice; | |
140 | + /** | |
141 | + * 包装费用合计¥ | |
142 | + */ | |
143 | + @ExcelField(title = "包装费用合计¥", order = 25) | |
144 | + private Double packetTotalPrice; | |
145 | + /** | |
146 | + * 汇率 | |
147 | + */ | |
148 | + @ExcelField(title = "汇率", order = 26) | |
149 | + private Double exchangeRate; | |
150 | + /** | |
151 | + * 利润率 | |
152 | + */ | |
153 | + @ExcelField(title = "利润率", order = 27) | |
154 | + private Double profitRate; | |
155 | + | |
156 | + /** | |
157 | + * 想法来源 | |
158 | + */ | |
159 | + @ExcelField(title = "想法来源", order = 28) | |
160 | + private String ideaSource; | |
161 | + /** | |
162 | + * 手工初型 | |
163 | + */ | |
164 | + @ExcelField(title = "手工初型", order = 29) | |
165 | + private String manualPreform; | |
166 | + /** | |
167 | + * 想法和手工比例分配 | |
168 | + */ | |
169 | + @ExcelField(title = "想法和手工比例分配", order = 30) | |
170 | + private Double ideaManualRate; | |
171 | + | |
172 | + | |
173 | + /** | |
174 | + * pp date | |
175 | + */ | |
176 | + @ExcelField(title = "pp date", order = 31) | |
177 | + private String ppTime; | |
178 | + /** | |
179 | + * pp样品确认意见 | |
180 | + */ | |
181 | + @ExcelField(title = "pp样品确认意见", order = 32) | |
182 | + private String ppConfirmResult; | |
183 | + /** | |
184 | + * EXTRA,SHOWROOM,ONLINE sample发送时间 | |
185 | + */ | |
186 | + @ExcelField(title = "EXTRA,SHOWROOM,ONLINE sample发送时间", order = 32) | |
187 | + private String esoSampleSendTime; | |
188 | + /** | |
189 | + * shippment sample 发送时间 | |
190 | + */ | |
191 | + @ExcelField(title = "shippment sample 发送时间", order = 33) | |
192 | + private String shippmentSampleSendTime; | |
193 | + /** | |
194 | + * shipment sample确认意见 | |
195 | + */ | |
196 | + @ExcelField(title = "shipment sample确认意见", order = 34) | |
197 | + private String shippmentSampleConfirmResult; | |
198 | + /** | |
199 | + * 自测通过时间 | |
200 | + */ | |
201 | + @ExcelField(title = "自测通过时间", order = 35) | |
202 | + private String selfTestPassTime; | |
203 | + /** | |
204 | + * Aitex测试发送时间 | |
205 | + */ | |
206 | + @ExcelField(title = "Aitex测试发送时间", order = 36) | |
207 | + private String aitexTestSendTime; | |
208 | + /** | |
209 | + * Aitex测试结果 | |
210 | + */ | |
211 | + @ExcelField(title = "Aitex测试结果", order = 37) | |
212 | + private String aitexTestFinishResult; | |
213 | + /** | |
214 | + * SGS测试发送时间 | |
215 | + */ | |
216 | + @ExcelField(title = "SGS测试发送时间", order = 38) | |
217 | + private String sgsTestSendTime; | |
218 | + /** | |
219 | + * SGS测试结果 | |
220 | + */ | |
221 | + @ExcelField(title = "SGS测试结果", order = 39) | |
222 | + private String sgsTestFinishResult; | |
223 | + /** | |
224 | + * Barcode sticker arrival time | |
225 | + */ | |
226 | + @ExcelField(title = "Barcode sticker arrival time", order = 40) | |
227 | + private String barcodeStickerArrivalTime; | |
228 | + /** | |
229 | + * 最晚包材到货时间 | |
230 | + */ | |
231 | + @ExcelField(title = "最晚包材到货时间", order = 41) | |
232 | + private String latestArrivalTime; | |
233 | + /** | |
234 | + * 最晚订舱+报关资料时间 | |
235 | + */ | |
236 | + @ExcelField(title = "最晚订舱+报关资料时间", order = 42) | |
237 | + private String latestBkTime; | |
238 | + | |
239 | + | |
240 | + /** | |
241 | + * 中期验货申请时间 | |
242 | + */ | |
243 | + @ExcelField(title = "中期验货申请时间", order = 43) | |
244 | + private String midCheckApplyTime; | |
245 | + /** | |
246 | + * 中期验货(功能性-拉力/跌落等、外观性-颜色/规格等、耐久性-烤厅等) | |
247 | + */ | |
248 | + @ExcelField(title = "中期验货(功能性-拉力/跌落等、外观性-颜色/规格等、耐久性-烤厅等)", order = 44) | |
249 | + private String midCheckComment; | |
250 | + /** | |
251 | + * 中期验货结果PASS / FAIL | |
252 | + */ | |
253 | + @ExcelField(title = "中期验货结果PASS / FAIL", order = 45) | |
254 | + private String midCheckResult; | |
255 | + /** | |
256 | + * 尾期验货申请时间 | |
257 | + */ | |
258 | + @ExcelField(title = "尾期验货申请时间", order = 46) | |
259 | + private String endCheckApplyTime; | |
260 | + /** | |
261 | + * 长度/规格 | |
262 | + */ | |
263 | + @ExcelField(title = "长度/规格", order = 47) | |
264 | + private String specification; | |
265 | + /** | |
266 | + * 功能性不良 | |
267 | + */ | |
268 | + @ExcelField(title = "功能性不良", order = 48) | |
269 | + private String functionality; | |
270 | + /** | |
271 | + * 电镀不良 | |
272 | + */ | |
273 | + @ExcelField(title = "电镀不良", order = 49) | |
274 | + private String electroplate; | |
275 | + /** | |
276 | + * 不良1 | |
277 | + */ | |
278 | + @ExcelField(title = "不良1", order = 50) | |
279 | + private String value1; | |
280 | + /** | |
281 | + * 不良2 | |
282 | + */ | |
283 | + @ExcelField(title = "不良2", order = 51) | |
284 | + private String value2; | |
285 | + /** | |
286 | + * 其他不良3 | |
287 | + */ | |
288 | + @ExcelField(title = "其他不良3", order = 52) | |
289 | + private String value3; | |
290 | + /** | |
291 | + * 包装:卡片、条码、箱贴,箱单 | |
292 | + */ | |
293 | + @ExcelField(title = "包装:卡片、条码、箱贴,箱单", order = 53) | |
294 | + private String boxPacket; | |
295 | + /** | |
296 | + * 尾期验货结果PASS / FAIL | |
297 | + */ | |
298 | + @ExcelField(title = "尾期验货结果PASS / FAIL", order = 54) | |
299 | + private String endCheckResult; | |
300 | + | |
301 | + | |
302 | +} | ... | ... |
src/main/java/com/order/erp/domain/vo/admin/AdminRoleSmallVO.java
0 → 100644
1 | +package com.order.erp.domain.vo.admin; | |
2 | + | |
3 | +import lombok.*; | |
4 | +import lombok.experimental.SuperBuilder; | |
5 | + | |
6 | +import java.io.Serializable; | |
7 | + | |
8 | +/** | |
9 | + * 角色表(AdminRole)实体类 | |
10 | + * | |
11 | + * @author makejava | |
12 | + * @since 2023-08-30 17:51:48 | |
13 | + */ | |
14 | +@Data | |
15 | +@AllArgsConstructor | |
16 | +@ToString | |
17 | +@NoArgsConstructor | |
18 | +@EqualsAndHashCode(callSuper = false) | |
19 | +@SuperBuilder | |
20 | +public class AdminRoleSmallVO implements Serializable { | |
21 | + | |
22 | + private Long id; | |
23 | + /** | |
24 | + * 角色名称 | |
25 | + */ | |
26 | + private String name; | |
27 | + | |
28 | + /** | |
29 | + * 角色code | |
30 | + */ | |
31 | + private String code; | |
32 | + | |
33 | + | |
34 | +} | ... | ... |
src/main/java/com/order/erp/domain/vo/admin/UpdatePwdVO.java
0 → 100644
1 | +package com.order.erp.domain.vo.admin; | |
2 | + | |
3 | +import lombok.*; | |
4 | +import lombok.experimental.SuperBuilder; | |
5 | + | |
6 | +import javax.validation.constraints.NotBlank; | |
7 | +import javax.validation.constraints.NotNull; | |
8 | +import java.io.Serializable; | |
9 | + | |
10 | +/** | |
11 | + * 用户表(AdminUser)实体类 | |
12 | + * | |
13 | + * @author makejava | |
14 | + * @since 2023-08-30 17:51:48 | |
15 | + */ | |
16 | +@Data | |
17 | +@AllArgsConstructor | |
18 | +@ToString | |
19 | +@NoArgsConstructor | |
20 | +@EqualsAndHashCode(callSuper = false) | |
21 | +@SuperBuilder | |
22 | +public class UpdatePwdVO implements Serializable { | |
23 | + | |
24 | + /** | |
25 | + * 用户id | |
26 | + */ | |
27 | + @NotNull(message = "密钥id不存在!") | |
28 | + private Long userId; | |
29 | + | |
30 | + /** | |
31 | + * 密码 | |
32 | + */ | |
33 | + @NotBlank(message = "要修改的密码不能为空") | |
34 | + private String password; | |
35 | + | |
36 | + /** | |
37 | + * 确认密码 | |
38 | + */ | |
39 | + @NotBlank(message = "请二次确认要修改的密码") | |
40 | + private String confirmPassword; | |
41 | + | |
42 | +} | |
43 | + | ... | ... |
src/main/java/com/order/erp/security/service/UserDetailsServiceImpl.java
1 | 1 | package com.order.erp.security.service; |
2 | 2 | |
3 | +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; | |
4 | +import com.order.erp.common.constant.Constant; | |
3 | 5 | import com.order.erp.common.exception.BusinessException; |
6 | +import com.order.erp.domain.RoleEnum; | |
4 | 7 | import com.order.erp.domain.vo.UserVO; |
8 | +import com.order.erp.domain.vo.admin.AdminRoleSmallVO; | |
5 | 9 | import com.order.erp.domain.vo.admin.DeptSmallVO; |
6 | 10 | import com.order.erp.domain.vo.admin.JobSmallVO; |
11 | +import com.order.erp.domain.vo.admin.RoleSmallVO; | |
7 | 12 | import com.order.erp.security.vo.JwtUser; |
8 | 13 | import com.order.erp.service.admin.AdminRoleService; |
9 | 14 | import com.order.erp.service.admin.AdminUserService; |
... | ... | @@ -14,8 +19,8 @@ import org.springframework.transaction.annotation.Propagation; |
14 | 19 | import org.springframework.transaction.annotation.Transactional; |
15 | 20 | |
16 | 21 | import javax.annotation.Resource; |
17 | -import java.util.Objects; | |
18 | -import java.util.Optional; | |
22 | +import java.util.*; | |
23 | +import java.util.stream.Collectors; | |
19 | 24 | |
20 | 25 | /** |
21 | 26 | * @date 2018-11-22 |
... | ... | @@ -62,7 +67,24 @@ public class UserDetailsServiceImpl implements UserDetailsService { |
62 | 67 | roleService.mapToGrantedAuthorities(user), |
63 | 68 | user.getEnabled(), |
64 | 69 | user.getCreateTime(), |
70 | + buildRoleSmall(user), | |
65 | 71 | user.getPwdResetTime() |
66 | 72 | ); |
67 | 73 | } |
74 | + | |
75 | + /** | |
76 | + * @param user | |
77 | + * @return | |
78 | + */ | |
79 | + private AdminRoleSmallVO buildRoleSmall(UserVO user) { | |
80 | + Set<RoleSmallVO> roleSmallVOS = user.getRoles(); | |
81 | + List<AdminRoleSmallVO> roleSmallVOList = new ArrayList<>(); | |
82 | + if (CollectionUtils.isNotEmpty(roleSmallVOS)) { | |
83 | + roleSmallVOList = roleSmallVOS.stream().map(x -> { | |
84 | + return AdminRoleSmallVO.builder().id(x.getId()) | |
85 | + .code(RoleEnum.getCodeById(x.getId())).name(RoleEnum.getNameById(x.getId())).build(); | |
86 | + }).collect(Collectors.toList()); | |
87 | + } | |
88 | + return CollectionUtils.isNotEmpty(roleSmallVOList) ? roleSmallVOList.get(Constant.ZERO) : null; | |
89 | + } | |
68 | 90 | } | ... | ... |
src/main/java/com/order/erp/security/vo/JwtUser.java
1 | 1 | package com.order.erp.security.vo; |
2 | 2 | |
3 | 3 | import com.fasterxml.jackson.annotation.JsonIgnore; |
4 | +import com.order.erp.domain.vo.admin.AdminRoleSmallVO; | |
4 | 5 | import lombok.AllArgsConstructor; |
5 | 6 | import lombok.Getter; |
6 | 7 | import org.springframework.security.core.GrantedAuthority; |
... | ... | @@ -8,7 +9,6 @@ import org.springframework.security.core.userdetails.UserDetails; |
8 | 9 | |
9 | 10 | import java.time.LocalDateTime; |
10 | 11 | import java.util.Collection; |
11 | -import java.util.Date; | |
12 | 12 | import java.util.stream.Collectors; |
13 | 13 | |
14 | 14 | /** |
... | ... | @@ -46,6 +46,8 @@ public class JwtUser implements UserDetails { |
46 | 46 | |
47 | 47 | private LocalDateTime createTime; |
48 | 48 | |
49 | + private AdminRoleSmallVO roleSmallVO; | |
50 | + | |
49 | 51 | @JsonIgnore |
50 | 52 | private final LocalDateTime lastPasswordResetDate; |
51 | 53 | ... | ... |
src/main/java/com/order/erp/service/admin/AdminUserService.java
... | ... | @@ -39,7 +39,6 @@ public interface AdminUserService extends IService<AdminUserDO> { |
39 | 39 | ServerResult add(AdminUserVO adminUserVO); |
40 | 40 | |
41 | 41 | /** |
42 | - * | |
43 | 42 | * @param adminUserVO |
44 | 43 | * @return |
45 | 44 | */ |
... | ... | @@ -62,6 +61,14 @@ public interface AdminUserService extends IService<AdminUserDO> { |
62 | 61 | ServerResult deleteById(AdminUserQueryVO adminUserQueryVO); |
63 | 62 | |
64 | 63 | /** |
64 | + * 修改密码 | |
65 | + * | |
66 | + * @param pwdVO | |
67 | + * @return | |
68 | + */ | |
69 | + ServerResult updatePass(UpdatePwdVO pwdVO); | |
70 | + | |
71 | + /** | |
65 | 72 | * 用户名称/手机号/邮箱号 |
66 | 73 | * |
67 | 74 | * @param userName | ... | ... |
src/main/java/com/order/erp/service/admin/impl/AdminUserServiceImpl.java
... | ... | @@ -36,6 +36,7 @@ import org.springframework.security.crypto.password.PasswordEncoder; |
36 | 36 | import org.springframework.stereotype.Service; |
37 | 37 | |
38 | 38 | import javax.annotation.Resource; |
39 | +import java.time.LocalDateTime; | |
39 | 40 | import java.util.*; |
40 | 41 | import java.util.stream.Collectors; |
41 | 42 | |
... | ... | @@ -160,6 +161,9 @@ public class AdminUserServiceImpl extends ServiceImpl<AdminUserMapper, AdminUser |
160 | 161 | adminUserVO.setId(null); |
161 | 162 | } |
162 | 163 | AdminUserDO adminUserDo = BeanUtil.copyProperties(adminUserVO, AdminUserDO.class); |
164 | + if (Objects.isNull(adminUserDo.getDeptId())) { | |
165 | + adminUserDo.setDeptId(1L); | |
166 | + } | |
163 | 167 | adminUserDo.setPassword(passwordEncoder.encode("123456")); |
164 | 168 | save(adminUserDo); |
165 | 169 | |
... | ... | @@ -285,6 +289,20 @@ public class AdminUserServiceImpl extends ServiceImpl<AdminUserMapper, AdminUser |
285 | 289 | return ServerResult.success(buildLoginUser(loginByPwdVO)); |
286 | 290 | } |
287 | 291 | |
292 | + @Override | |
293 | + public ServerResult updatePass(UpdatePwdVO pwdVO) { | |
294 | + if (!pwdVO.getPassword().equals(pwdVO.getConfirmPassword())) { | |
295 | + throw new BusinessException(ServerResultCode.MEMBER_CONFIRM_PASSWORD_ERROR); | |
296 | + } | |
297 | + AdminUserDO userDO = getById(pwdVO.getUserId()); | |
298 | + if (Objects.isNull(userDO)) { | |
299 | + throw new BusinessException(ServerResultCode.USER_NOT_EXIT); | |
300 | + } | |
301 | + userDO.setPwdResetTime(LocalDateTime.now()); | |
302 | + userDO.setPassword(passwordEncoder.encode(pwdVO.getPassword())); | |
303 | + updateById(userDO); | |
304 | + return ServerResult.success(); | |
305 | + } | |
288 | 306 | |
289 | 307 | /** |
290 | 308 | * @param loginByPwdVO | ... | ... |
src/main/java/com/order/erp/service/order/OrderBaseInfoService.java
... | ... | @@ -2,9 +2,13 @@ package com.order.erp.service.order; |
2 | 2 | |
3 | 3 | import com.baomidou.mybatisplus.extension.service.IService; |
4 | 4 | import com.order.erp.common.constant.ServerResult; |
5 | +import com.order.erp.common.excel4j.exceptions.Excel4JException; | |
5 | 6 | import com.order.erp.domain.dto.order.OrderBaseInfoDO; |
6 | 7 | import com.order.erp.domain.vo.order.*; |
7 | 8 | |
9 | +import javax.servlet.http.HttpServletResponse; | |
10 | +import java.io.IOException; | |
11 | + | |
8 | 12 | /** |
9 | 13 | * 订单基础信息表(OrderBaseInfo)表服务接口 |
10 | 14 | * |
... | ... | @@ -39,6 +43,14 @@ public interface OrderBaseInfoService extends IService<OrderBaseInfoDO> { |
39 | 43 | |
40 | 44 | /** |
41 | 45 | * |
46 | + * @param response | |
47 | + * @param orderBaseInfoQueryVO | |
48 | + * @return | |
49 | + */ | |
50 | + ServerResult export(HttpServletResponse response, OrderBaseInfoQueryVO orderBaseInfoQueryVO) throws IOException, Excel4JException; | |
51 | + | |
52 | + /** | |
53 | + * | |
42 | 54 | * @param fieldVO |
43 | 55 | * @return |
44 | 56 | */ | ... | ... |
src/main/java/com/order/erp/service/order/impl/OrderBaseInfoServiceImpl.java
... | ... | @@ -13,6 +13,8 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
13 | 13 | import com.canrd.shop.common.constant.ServerResultCode; |
14 | 14 | import com.order.erp.common.constant.Constant; |
15 | 15 | import com.order.erp.common.constant.ServerResult; |
16 | +import com.order.erp.common.excel4j.ExcelUtils; | |
17 | +import com.order.erp.common.excel4j.exceptions.Excel4JException; | |
16 | 18 | import com.order.erp.common.exception.BusinessException; |
17 | 19 | import com.order.erp.common.utils.OrderFieldUtils; |
18 | 20 | import com.order.erp.config.DataScope; |
... | ... | @@ -22,6 +24,7 @@ import com.order.erp.domain.OrderLockFieldEnum; |
22 | 24 | import com.order.erp.domain.OrderStatusEnum; |
23 | 25 | import com.order.erp.domain.dto.BaseDO; |
24 | 26 | import com.order.erp.domain.dto.order.*; |
27 | +import com.order.erp.domain.excel.OrderExcelVO; | |
25 | 28 | import com.order.erp.domain.vo.order.*; |
26 | 29 | import com.order.erp.mapper.order.OrderBaseInfoMapper; |
27 | 30 | import com.order.erp.service.order.*; |
... | ... | @@ -30,6 +33,8 @@ import org.springframework.beans.BeanUtils; |
30 | 33 | import org.springframework.stereotype.Service; |
31 | 34 | |
32 | 35 | import javax.annotation.Resource; |
36 | +import javax.servlet.http.HttpServletResponse; | |
37 | +import java.io.IOException; | |
33 | 38 | import java.util.List; |
34 | 39 | import java.util.Map; |
35 | 40 | import java.util.Objects; |
... | ... | @@ -137,6 +142,45 @@ public class OrderBaseInfoServiceImpl extends ServiceImpl<OrderBaseInfoMapper, O |
137 | 142 | } |
138 | 143 | |
139 | 144 | @Override |
145 | + public ServerResult export(HttpServletResponse response, OrderBaseInfoQueryVO queryVO) throws IOException, Excel4JException { | |
146 | + LambdaQueryWrapper<OrderBaseInfoDO> queryWrapper = buildQueryByParam(queryVO); | |
147 | + List<OrderBaseInfoDO> orderBaseInfoDOList = list(queryWrapper); | |
148 | + if (CollectionUtils.isNotEmpty(orderBaseInfoDOList)) { | |
149 | + List<OrderInfoResultVO> resultVOList = orderBaseInfoDOList.stream().map(x -> { | |
150 | + OrderInfoResultVO resultVO = new OrderInfoResultVO(); | |
151 | + BeanUtils.copyProperties(x, resultVO); | |
152 | + return resultVO; | |
153 | + }).collect(Collectors.toList()); | |
154 | + | |
155 | + // 填充利润分析 | |
156 | + fillProfitAnalysisInfo(resultVOList); | |
157 | + | |
158 | + // 填充项目报告 | |
159 | + fillReportInfo(resultVOList); | |
160 | + | |
161 | + // 填充跟单信息 | |
162 | + fillTrackStageInfo(resultVOList); | |
163 | + | |
164 | + // 填充质检信息 | |
165 | + fillInspectionStageInfo(resultVOList); | |
166 | + | |
167 | + if (CollectionUtils.isNotEmpty(resultVOList)) { | |
168 | + List<OrderExcelVO> excelVOS = resultVOList.stream().map(x -> { | |
169 | + OrderExcelVO excelVO = new OrderExcelVO(); | |
170 | + BeanUtils.copyProperties(x, excelVO); | |
171 | + return excelVO; | |
172 | + }).collect(Collectors.toList()); | |
173 | + //response为HttpServletResponse对象 | |
174 | + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8"); | |
175 | + //test.xls是弹出下载对话框的文件名,不能为中文,中文请自行编码 | |
176 | + response.setHeader("Content-Disposition", "attachment;filename=order.xlsx"); | |
177 | + ExcelUtils.getInstance().exportObjects2Excel(excelVOS, OrderExcelVO.class, response.getOutputStream()); | |
178 | + } | |
179 | + } | |
180 | + return ServerResult.success(); | |
181 | + } | |
182 | + | |
183 | + @Override | |
140 | 184 | public ServerResult fieldUnlockApply(OrderUnlockFieldApplyVO fieldVO) { |
141 | 185 | Long userId = dataScope.getLoginUserId(); |
142 | 186 | checkApply(fieldVO, userId); | ... | ... |