1 工具类:
2 import com.github.pagehelper.util.StringUtil;
6 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
7 import org.apache.poi.ss.usermodel.*;
8 import org.apache.poi.ss.util.CellRangeAddress;
9 import org.apache.poi.xssf.usermodel.*;
10 import org.springframework.util.StringUtils;
11 import org.springframework.web.multipart.MultipartFile;
12
13 import javax.servlet.http.HttpServletResponse;
14 import java.io.IOException;
15 import java.io.InputStream;
16 import java.io.OutputStream;
17 import java.util.Date;
18 import java.util.List;
19
20
21 public class ExcelUtil {
22
23 private ExcelUtil() { throw new IllegalStateException("Utility class"); }
24
25 public static String getPostfix(String path) {
26 String pathContains = ".";
27 if (StringUtils.isEmpty(path) || !path.contains(pathContains)) {
28 return null;
29 }
30 return path.substring(path.lastIndexOf(pathContains) + 1, path.length()).trim();
31 }
32
33 /**
34 * 解析Excel文件
35 *
36 * @return
37 */
38 public static Workbook analysisExcelFile(MultipartFile file) throws BusinessException {
39 if (file == null || file.getSize() == 0) {
40 throw new BusinessException("不能上传空文件");
41 }
42 //得到文件名称
43 String fileName = file.getOriginalFilename();
44 //获取文件的拓展名
45 String postfix = ExcelUtil.getPostfix(fileName);
46
47 Workbook workbook;
48 try {
49 InputStream is = file.getInputStream();
50 String fileType = "xlsx";
51 if (fileType.equals(postfix)) {
52 workbook = new XSSFWorkbook(is);
53 } else {
54 workbook = new HSSFWorkbook(is);
55 }
56 } catch (IOException e) {
57 throw new BusinessException("文件解析失败");
58 }
59 if (workbook == null || workbook.getSheetAt(0) == null) {
60 throw new BusinessException("不能上传空文件");
61 }
62 return workbook;
63 }
64
65 /**
66 * 将Cell定义为文本类型,取值
67 *
68 * @param cell Cell
69 * @return 字符串格式的值
70 */
71 public static String getCellStringValue(Cell cell) {
72 if (cell == null) {
73 return "";
74 }
75 cell.setCellType(CellType.STRING);
76 return cell.getStringCellValue();
77 }
78
79 /**
80 * 判断上传文件表头是否正确
81 *
82 * @param titleRow 标题行
83 * @param titleValues 模板标题
84 * @return true/false
85 */
86 public static boolean validExcelTitle(Row titleRow, String[] titleValues) {
87 if (titleRow == null) {
88 // 模板不正确
89 return false;
90 }
91 //判断上传文件的标题行是否符合
92 for (int i = 0; i < titleValues.length; i++) {
93 String titleValue = titleValues[i];
94 Cell cell = titleRow.getCell(i);
95 if (cell == null) {
96 return false;
97 }
98 String cellValue = cell.getStringCellValue();
99 if (!titleValue.equals(cellValue)) {
100 return false;
101 }
102 }
103
104 return true;
105 }
106
107 /**
108 * 验证关键数据不为空
109 *
110 * @param rowItem 行号
111 * @param valueList 数据
112 * @param item 验证字段序号
113 */
114 public static String validKeyValue(int rowItem, List<String> valueList, String[] titleNames, int[] item) {
115 boolean isEmpty = true;
116 Integer firstEmptyItem = null;
117 for (int i : item) {
118 if (StringUtil.isEmpty(valueList.get(i))) {
119 if (firstEmptyItem == null) {
120 firstEmptyItem = i;
121 }
122 if (!isEmpty) {
123 break;
124 }
125 } else {
126 isEmpty = false;
127 }
128 }
129
130 if (isEmpty) {
131 return "第" + rowItem + "行为空数据";
132 } else if (firstEmptyItem != null) {
133 return "第" + rowItem + "行的" + titleNames[firstEmptyItem] + "为空";
134 }
135
136 return null;
137 }
138
139 /**
140 * 生成Excel2007
141 *
142 * @param title 报表名称
143 * @param headers 标题行名称
144 * @return XSSFWorkbook
145 */
146 private static XSSFWorkbook exportExcel2007(String sheetName, String title, String[] headers) {
147 // 声明一个工作薄
148 XSSFWorkbook workbook = new XSSFWorkbook();
149 // 生成一个表格
150 XSSFSheet sheet;
151 if (StringUtils.isEmpty(sheetName)) {
152 sheet = workbook.createSheet();
153 } else {
154 sheet = workbook.createSheet(sheetName);
155 }
156
157 // 创建标题样式1
158 XSSFCellStyle headerStyle = workbook.createCellStyle();
159 XSSFFont headerFont = workbook.createFont();
160 headerFont.setBold(true);
161 headerFont.setFontHeightInPoints((short) 20);
162 headerStyle.setFont(headerFont);
163 headerStyle.setAlignment(HorizontalAlignment.CENTER);
164 // 创建标题样式1
165 XSSFCellStyle titleStyle = workbook.createCellStyle();
166 XSSFFont titleFont = workbook.createFont();
167 titleFont.setBold(true);
168 titleFont.setFontHeightInPoints((short) 10);
169 titleStyle.setFont(titleFont);
170 titleStyle.setAlignment(HorizontalAlignment.CENTER);
171 // 产生表格标题行
172 XSSFRow row = sheet.createRow(0);
173 //报表名称
174 sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, headers.length - 1));
175 XSSFCell cellTitle = row.createCell(0);
176 cellTitle.setCellValue(title);
177 cellTitle.setCellStyle(headerStyle);
178
179 XSSFRow rowHeader = sheet.createRow(1);
180 XSSFCell cellHeader;
181 for (int i = 0; i < headers.length; i++) {
182 cellHeader = rowHeader.createCell(i);
183 cellHeader.setCellValue(new XSSFRichTextString(headers[i]));
184 cellHeader.setCellStyle(titleStyle);
185 }
186
187 return workbook;
188 }
189
190
191
192 /**
193 * 生成Excel2007
194 *
195 * @param set Excel生成参数
196 * @param response 服务器响应
197 * @return
198 */
199 public static void exportExcel2007(ExcelSet set, HttpServletResponse response) {
200 // 声明一个工作薄
201 XSSFWorkbook workbook = exportExcel2007(set.getSheetName(), set.getReportName(), set.getTitleName());
202
203 List<String[]> values = set.getValues();
204 if (values != null && !values.isEmpty()) {
205 // 生成一个表格
206 XSSFSheet sheet = workbook.getSheetAt(0);
207 for (int i = 0; i < values.size(); i++) {
208 XSSFRow valueRow = sheet.createRow(i + 2);
209 String[] objs = values.get(i);
210 for (int j = 0; j < objs.length; j++) {
211 Cell cell = valueRow.createCell(j);
212 cell.setCellValue(objs[j]);
213 }
214 }
215 }
216
217 setResponseHeader(response, set.getFileName());
218 try {
219 OutputStream os = response.getOutputStream();
220 workbook.write(os);
221 os.flush();
222 os.close();
223 } catch (IOException e) {
224 e.printStackTrace();
225 }
226 }
227
228 /**
229 * 发送响应流方法
230 *
231 * @param response 服务器响应
232 * @param fileName 下载文件的文件名
233 */
234 private static void setResponseHeader(HttpServletResponse response, String fileName) {
235 try {
236 response.reset();
237 String charsetName = "UTF-8";
238 fileName = new String(fileName.getBytes(), charsetName);
239 //通知客服文件的MIME类型
240 response.setContentType("application/vnd.ms-excel;charset=UTF-8");
241 response.setHeader("Content-disposition", "attachment;filename=" + fileName);
242 response.addHeader("Transfer-Encoding","chunked");
243
244 } catch (Exception ex) {
245 ex.printStackTrace();
246 }
247 }
248
249 /**
250 * 生成导出Excel文件名称
251 * @param did 经销商编码
252 * @return String
253 */
254 public static String getExcelFileName(String did){
255 String nowStr = DateUtil.formartDate(new Date(),"yyyyMMddHHmmss");
256 return did+"_"+nowStr+".xlsx";
257 }
258 }
259
260
261 Service:
262 @Transactional(rollbackFor = Exception.class)
263 public List<String> uploadSupplierExcelFile(String pDid,String pUserId,MultipartFile pExcelFile) throws BusinessException {
264 // 解析文件
265 Workbook workbook = ExcelUtil.analysisExcelFile(pExcelFile);
266 // 获取文件的第一个sheet页
267 Sheet sheet = workbook.getSheetAt(0);
268 //验证模板是否正确
269 //模板表头标题内容
270 String [] titleValues = ExcelTitle.EXCEL_SUPPLIER_TITLE;
271 Row firstRow = sheet.getRow(0);
272 if(!ExcelUtil.validExcelTitle(firstRow,titleValues)){
273 throw new BusinessException("上传模板错误");
274 }
275
276 //错误信息保存集合
277 List<String> templateErrorList = new ArrayList<>();
278 //保存<供应商编号,DID>,用于检测,是否存在相同供应商
279 Map<String,String> cMap = new HashMap<>();
280 //要保存的供应商数据
281 List<BaseSupplier> baseSupplierList = new ArrayList<>();
282 //得到文件中最大行号
283 int lasrRowNum = sheet.getLastRowNum();
284 //最大读取列数
285 int maxColumn = 8;
286 // 开始数据处理
287 for(int rowNum = 1; rowNum <= lasrRowNum; rowNum++){
288 Row row = sheet.getRow(rowNum);
289 if(row == null){
290 continue;
291 }
292 int nowRowNum = rowNum + 1;
293 //得到行数据
294 List<String> valueList = new ArrayList<>(maxColumn);
295 for(int i=0;i<maxColumn;i++){
296 String value = ExcelUtil.getCellStringValue(row.getCell(i));
297 valueList.add(value);
298 }
299 //验证字段的序号
300 int [] validEnptyItem = {0,1,2,3,4,5,6,7};
301 String errorMsg = ExcelUtil.validKeyValue(nowRowNum,valueList,ExcelTitle.EXCEL_SUPPLIER_TITLE,validEnptyItem);
302 if(!StringUtils.isEmpty(errorMsg)){
303 templateErrorList.add(errorMsg);
304 }else{
305 BaseSupplier baseSupplier = new BaseSupplier();
306 baseSupplier.setSupplierName(valueList.get(0));
307 baseSupplier.setSubDept(valueList.get(1));
308 baseSupplier.setSubPerson(valueList.get(2));
309 baseSupplier.setSupplierType(valueList.get(3));
310 baseSupplier.setRate(valueList.get(4));
311 baseSupplier.setLinkman(valueList.get(5));
312 baseSupplier.setPhone(valueList.get(6));
313 baseSupplier.setAddr(valueList.get(7));
314 //判断本条数据是否存在空数据
315 if(validExcelData(nowRowNum,baseSupplier,templateErrorList,cMap)){
316 String newRowId = codeGenerationService.generateCode(CodeCom.CODE_SUPPLIER_PRE);
317 baseSupplier.setRowId(newRowId);
318 baseSupplier.setUserid(pUserId);
319 //将数据加入到供应商列表中
320 baseSupplierList.add(baseSupplier);
321 }
322 }
323
324 }
325
326 if(baseSupplierList.isEmpty()){
327 templateErrorList.add("文件中无有效数据");
328 }
329 //保存导入数据
330 if(templateErrorList.isEmpty()){
331 saveBaseSuppilerrBatch(baseSupplierList);
332 }
333
334
335 return templateErrorList;
336 }
337
338 controller:
339
340 /**
341 * 批量保存供应商信息
342 * @param pBaseSuppliers 供应商信息
343 * @return int
344 */
345 @Transactional(rollbackFor = Exception.class)
346 public int saveBaseSuppilerrBatch(List<BaseSupplier> pBaseSuppliers){
347 //分批次保存信息供应商信息
348 //每批保存200条数据
349 Integer batchCount = 200;
350 int count = 0;
351 for (int i = 0; i < Math.ceil(pBaseSuppliers.size()/batchCount.doubleValue()); i++) {
352 List<BaseSupplier> zBaseCustomers = pBaseSuppliers.subList(i * batchCount,
353 (i + 1) * batchCount > pBaseSuppliers.size() ? pBaseSuppliers.size() : (i + 1) * batchCount);
354 int zCount = baseSupplierMapper.insertBatch(zBaseCustomers);
355 count += zCount;
356 }
357 return count;
358 }
359
360 private boolean validExcelData(int pRowNum,BaseSupplier pSupplier,
361 List<String> pTemplateErrorList,
362 Map<String,String> cMap){
363
364 //判断是否已有重复供应商数据
365 String cNameHave = cMap.get(pSupplier.getSupplierName());
366 if(cNameHave==null){
367 cMap.put(pSupplier.getSupplierName(),pSupplier.getSupplierName());
368 }else{
369 pTemplateErrorList.add("第"+pRowNum+"行的供应商名称重复!");
370 return false;
371 }
372 //查询已存在的数据,判断供应商名称是否已经存在
373 int count = countByAlikeName(null,pSupplier.getSupplierName());
374 if(count>0){
375 pTemplateErrorList.add("第"+pRowNum+"行的供应商名称已存在!");
376 return false;
377 }
378 return true;
379 }
380 /**
381 * 根据名称查询符合条件的数据数量
382 * @param pRowId 查询时不过滤的供应商编码
383 * @param pName 供应商名称
384 * @return 执行行数
385 */
386 public int countByAlikeName(String pRowId,String pName){
387 BaseSupplierExample example = new BaseSupplierExample();
388 BaseSupplierExample.Criteria criteria = example.createCriteria();
389 criteria.andSupplierNameLike(pName);
390 if(pRowId!=null){
391 criteria.andRowIdNotEqualTo(pRowId);
392 }
393 return baseSupplierMapper.countByExample(example);
394 }
395
396 保存方法:
397 /**
398 * 批量导入供应商数据
399 * @param pExcelFile
400 * @return
401 */
402 @ApiOperation(value = "批量导入供应商资料", notes = "批量导入供应商资料")
403 @PostMapping(value = "/uploadSupplierExcelFile")
404 public JsonResult uploadCustomerExcelFile(
405 @ApiParam(name = "pExcelFile", value = "导入文件", required = true)
406 @RequestParam("pExcelFile") MultipartFile pExcelFile) {
407 UserInfo info = this.getUserInfo();
408 String pDid = info.getDid();
409 String pUserId = info.getUserId();
410 logger.info("批量导入供应商资料接口请求参数,pDid:{},pUserId:{}", pDid, pUserId);
411 try {
412 List<String> errorMsgList = baseSupplierService.uploadSupplierExcelFile(pDid, pUserId, pExcelFile);
413 if (errorMsgList != null && !errorMsgList.isEmpty()) {
414 return JsonResult.get(HttpReturnEnums.ParaError, errorMsgList);
415 }
416 } catch (BusinessException e) {
417 return JsonResult.get(HttpReturnEnums.ParaError, null, e.getMessage());
418 }
419 return JsonResult.get(HttpReturnEnums.Success);
420 }
421
422 mapper:
423 int insertBatch(@Param("supplierList") List<BaseSupplier> record);
424
425 xml sql:
426 <insert id="insertBatch" parameterType="com.shinho.dc3.master.models.po.BaseSupplier" >
427 insert into base_supplier (
428 row_id, supplier_name, sub_dept,
429 sub_person, supplier_type, rate,
430 linkman, phone, addr,userid,did)
431 values
432 <foreach collection="supplierList" index="index" item="supplierList" separator=",">
433 (
434 #{supplierList.rowId,jdbcType=VARCHAR}, #{supplierList.supplierName,jdbcType=VARCHAR}, #{supplierList.subDept,jdbcType=VARCHAR},
435 #{supplierList.subPerson,jdbcType=VARCHAR}, #{supplierList.supplierType,jdbcType=VARCHAR}, #{supplierList.rate,jdbcType=VARCHAR},
436 #{supplierList.linkman,jdbcType=VARCHAR}, #{supplierList.phone,jdbcType=VARCHAR}, #{supplierList.addr,jdbcType=VARCHAR},
437 #{supplierList.userid,jdbcType=VARCHAR}, #{supplierList.did,jdbcType=VARCHAR}
438 )
439 </foreach>
440 </insert>
441 public class ExcelTitle {
442 /**
443 * EXCEL导入表头-供应商档案
444 */
445 public static final String [] EXCEL_SUPPLIER_TITLE = {"供应商名称","分管部门","分管人员","供应商类型","税率","联系人","联系电话","供应商地址"};
446 }