071081381eda0fac2bc07293cad9d683a5fe30d8.svn-base 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. package cn.com.goldenwater.dcproj.utils.impexcel;
  2. import cn.com.goldenwater.dcproj.utils.ZipUtil;
  3. import cn.com.goldenwater.dcproj.utils.impexcel.format.PblmFieldFormatExp;
  4. import cn.com.goldenwater.dcproj.utils.impexcel.format.PblmFieldFormatImp;
  5. import cn.com.goldenwater.id.util.UuidUtil;
  6. import org.apache.commons.collections.MapUtils;
  7. import org.apache.commons.io.FileUtils;
  8. import org.apache.commons.lang3.StringUtils;
  9. import org.apache.poi.hssf.usermodel.HSSFWorkbook;
  10. import org.apache.poi.ss.usermodel.Row;
  11. import org.apache.poi.ss.usermodel.Sheet;
  12. import org.apache.poi.ss.usermodel.Workbook;
  13. import org.apache.poi.xssf.usermodel.XSSFWorkbook;
  14. import org.springframework.web.multipart.MultipartFile;
  15. import javax.servlet.http.HttpServletResponse;
  16. import java.io.*;
  17. import java.lang.reflect.InvocationTargetException;
  18. import java.lang.reflect.Method;
  19. import java.net.URLEncoder;
  20. import java.util.*;
  21. import java.util.stream.Collectors;
  22. import static cn.com.goldenwater.dcproj.utils.expExcel.ExportAbstract.XLS;
  23. import static cn.com.goldenwater.dcproj.utils.export.FieldFormat.formatCheckNull;
  24. import static cn.com.goldenwater.dcproj.utils.impexcel.field.ExcelFieldLists.pblmFieldArrays;
  25. /**
  26. * <p>
  27. * 通用的导出导入工具类
  28. * </p>
  29. *
  30. * @author liyz
  31. * @date 2019/7/19 20:19
  32. **/
  33. public class ExpAndImpUtil {
  34. private static final String SHEET_NAME = "模板文件";
  35. /**
  36. * 功能:判断文件是否存在
  37. */
  38. public static File isExist(String originUrl) throws IOException {
  39. // 判断文件是否存在
  40. File file = new File(originUrl);
  41. if (!file.exists()) {
  42. throw new IOException("文件名为" + file.getName() + "Excel文件不存在!");
  43. }
  44. return file;
  45. }
  46. /**
  47. * 下载模板
  48. * @param response HttpServletResponse
  49. * @param list 从数据库里获取到的数据集
  50. * @param filePath 模板文件的路径,带上扩展名,如:D:\DC\template\moban.xls
  51. * @param startRow 从第几行开始写入数据 key行所在的行号-1
  52. * @param sheetName sheet名称
  53. * @throws Exception 异常
  54. */
  55. public static void download(HttpServletResponse response, List<Map<String,Object>> list, String filePath,int startRow,String sheetName) throws Exception{
  56. ByteArrayOutputStream os = new ByteArrayOutputStream();
  57. FileInputStream fis = null;
  58. if(StringUtils.isBlank(sheetName)){
  59. sheetName = SHEET_NAME;
  60. }
  61. try {
  62. // 获取模板
  63. fis = new FileInputStream(isExist(filePath));
  64. String fileExt = filePath.substring(filePath.lastIndexOf(".")).replace(".","");
  65. Workbook workBook = null;
  66. if(XLS.equals(fileExt)){
  67. workBook = new HSSFWorkbook(fis);
  68. }else {
  69. workBook = new XSSFWorkbook(fis);
  70. }
  71. workBook.setSheetName(0, sheetName);
  72. Sheet sheet = workBook.getSheetAt(0);
  73. for (int i = 0; i < list.size(); i++) {
  74. List<String> keys = new ArrayList<>();
  75. Row keyRow = sheet.getRow(startRow);
  76. for(int r=0;r<keyRow.getPhysicalNumberOfCells();r++){
  77. if(!"".equals(keyRow.getCell(r).toString())){
  78. keys.add(keyRow.getCell(r).toString());
  79. }
  80. }
  81. Row creRow = sheet.createRow(startRow + 1 + i);
  82. Map<String,Object> map = list.get(i);
  83. for(int j = 0;j < keys.size(); j++){
  84. Object val = map.get(keys.get(j));
  85. creRow.createCell(j).setCellValue(val == null ? "" : val.toString());
  86. }
  87. }
  88. workBook.write(os);
  89. fis.close();
  90. os.flush();
  91. os.close();
  92. ExportExcel.downloadExcelFile(response, os,sheetName + filePath.substring(filePath.lastIndexOf(".")));
  93. }catch (Exception e){
  94. e.printStackTrace();
  95. }finally {
  96. if(fis != null){
  97. fis.close();
  98. }
  99. os.close();
  100. }
  101. }
  102. /**
  103. * 下载Excel的重载方法(简化常用)
  104. *
  105. * @param response HttpServletResponse
  106. * @param os 字节数据输出流
  107. * @param fileName 文件名称
  108. */
  109. public static void downloadExcelFile(HttpServletResponse response, ByteArrayOutputStream os, String fileName) {
  110. ExportExcel.downloadExcelFile(response,os,fileName);
  111. }
  112. /**
  113. * 下载任意文件的方法
  114. *
  115. * @param response HttpServletResponse
  116. * @param filePath "D:/excel.xls"
  117. * @param fileName "水库问题"
  118. * @throws Exception 异常
  119. */
  120. public static void downloadFile(HttpServletResponse response, String filePath, String fileName) throws Exception {
  121. File file = new File(filePath);
  122. String ext = filePath.substring(filePath.lastIndexOf("."));
  123. fileName = fileName + ext;
  124. if (file.exists()) {
  125. response.setCharacterEncoding("UTF-8");
  126. response.setContentType("application/octet-stream");
  127. response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
  128. InputStream input = new FileInputStream(file);
  129. OutputStream os = response.getOutputStream();
  130. int len = 0;
  131. byte[] buffer = new byte[4096];
  132. while ((len = input.read(buffer, 0, buffer.length)) != -1) {
  133. os.write(buffer, 0, len);
  134. }
  135. input.close();
  136. os.flush();
  137. os.close();
  138. }
  139. }
  140. /**
  141. * 获取Workbook
  142. * @param list 数据集
  143. * @param filePath 模板路径
  144. * @param startRow 开始写入行
  145. * @param sheetName Sheet名称
  146. * @return Workbook
  147. * @throws Exception 异常
  148. */
  149. public static Workbook getWorkbook(List<Map<String,Object>> list, String filePath,int startRow,String sheetName) throws Exception{
  150. if(StringUtils.isBlank(sheetName)){
  151. sheetName = SHEET_NAME;
  152. }
  153. FileInputStream fis = null;
  154. Workbook workBook = null;
  155. try {
  156. // 获取模板
  157. fis = new FileInputStream(isExist(filePath));
  158. String fileExt = filePath.substring(filePath.lastIndexOf(".")+1);
  159. if(XLS.equals(fileExt)){
  160. workBook = new HSSFWorkbook(fis);
  161. }else {
  162. workBook = new XSSFWorkbook(fis);
  163. }
  164. workBook.setSheetName(0, sheetName);
  165. Sheet sheet = workBook.getSheetAt(0);
  166. for (int i = 0; i < list.size(); i++) {
  167. List<String> keys = new ArrayList<>();
  168. Row keyRow = sheet.getRow(startRow);
  169. for(int r=0;r<keyRow.getPhysicalNumberOfCells();r++){
  170. if(!"".equals(keyRow.getCell(r).toString())){
  171. keys.add(keyRow.getCell(r).toString());
  172. }
  173. }
  174. Row creRow = sheet.createRow(startRow + 1 + i);
  175. Map<String,Object> map = list.get(i);
  176. for(int j = 0;j < keys.size(); j++){
  177. Object val = map.get(keys.get(j));
  178. creRow.createCell(j).setCellValue(val == null ? "" : val.toString());
  179. }
  180. }
  181. fis.close();
  182. }catch (Exception e){
  183. e.printStackTrace();
  184. }finally {
  185. if(fis != null){
  186. fis.close();
  187. }
  188. }
  189. return workBook;
  190. }
  191. /**
  192. * 上传文件
  193. * @param file 文件流
  194. * @param folderPath 要存放的文件夹的路径
  195. * @return 生成的文件的路径
  196. * @throws IOException 异常
  197. */
  198. public static String upload(MultipartFile file,String folderPath) throws IOException {
  199. String fileName = UuidUtil.uuid();
  200. // .xls 格式的
  201. String ext = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
  202. File pathFile = new File(folderPath);
  203. if(!pathFile.exists()){
  204. pathFile.mkdirs();
  205. }
  206. FileUtils.copyInputStreamToFile(file.getInputStream(), new File(folderPath, fileName + ext ));
  207. return folderPath + File.separator + fileName + ext;
  208. }
  209. public static String uploadFileZipCommon(MultipartFile file,String folderPath) throws Exception{
  210. // 先存放到一个临时路径,再剪切或复制到图片路径下
  211. String filePath = ExpAndImpUtil.upload(file,folderPath);
  212. //解压到此文件夹
  213. ZipUtil.unzip(new File(filePath), folderPath);
  214. return filePath;
  215. }
  216. /**
  217. * 获取解析后的数据
  218. * @param filePath 文件存储路径
  219. * @param startRow 从第几行开始解析,注意把key那一行带上
  220. * @param clazz 格式化类
  221. * @return 解析后的数据
  222. * @throws IOException 异常
  223. */
  224. public static List<LinkedHashMap<String,Object>> parseData(String filePath, int startRow, Class<?> clazz) throws IOException {
  225. return ImportExcel.getParseData(filePath,startRow,0, clazz);
  226. }
  227. /**
  228. * 功能:把Map转成Bean (主要用于把从Excel解析出来的Map对象还原成实体类对象,方便入库)
  229. */
  230. public static Object convertMapToBean(Class<?> clazz, Map lhp) throws IllegalAccessException, InstantiationException {
  231. return ImportExcel.convertMapToBean(clazz,lhp);
  232. }
  233. /** 用反射简化赋值流程,通过对象和属性名称给Map赋值 */
  234. public static Map<String,Object> convertBeanToMap(Object obj, String[] names,Map map,Class<?> formatClazz) {
  235. if(map == null){
  236. map = new LinkedHashMap<>();
  237. }
  238. if(obj == null){
  239. for (String name : names){
  240. map.put(name,"");
  241. }
  242. return map;
  243. }
  244. Method[] methods = obj.getClass().getMethods();
  245. for(Method method : methods){
  246. for (String name : names){
  247. if(("get"+name).toLowerCase().equals(method.getName().toLowerCase())){
  248. try {
  249. map.put(name,ImportExcel.formatValue(name,formatCheckNull(method.invoke(obj)),formatClazz));
  250. } catch (IllegalAccessException e) {
  251. e.printStackTrace();
  252. } catch (InvocationTargetException e) {
  253. e.printStackTrace();
  254. }
  255. }
  256. }
  257. }
  258. return map;
  259. }
  260. public static List<Map<String,Object>> convertBeanToList(Object list, String[] names, Class<?> clazz) {
  261. List<Map<String,Object>> listMap = new ArrayList<>();
  262. for(Object obj : (List)list){
  263. Map<String,Object> dataMap = ExpAndImpUtil.convertBeanToMap(obj,pblmFieldArrays,null,clazz);
  264. listMap.add(dataMap);
  265. }
  266. return listMap;
  267. }
  268. /**
  269. * 获取展示到前台的数据,反格式化
  270. * @param parseData parseData
  271. * @param clazz 格式化类
  272. * @return showData
  273. * @throws IOException 异常
  274. */
  275. public static List<LinkedHashMap<String,Object>> showData(List<LinkedHashMap<String,Object>> parseData, Class<?> clazz) throws IOException {
  276. return ImportExcel.getShowData(parseData,clazz);
  277. }
  278. public static String getDateFormatPath(String basePath){
  279. return ImpUtil.getDateFormatPath(basePath);
  280. }
  281. /**
  282. * 导出EXCEL时动态创建一个下拉列表
  283. * @param groupNamesList 数据集
  284. * @param firstRow 下拉框从第几行开始,默认最终行结束
  285. * @param firstCol 下拉框从第几列开始
  286. * @return 输出流
  287. */
  288. public static ByteArrayOutputStream createListBox(String[] groupNamesList,int firstRow,int firstCol,Workbook workbook){
  289. return ExportExcel.createListBox(groupNamesList,firstRow,firstCol,workbook);
  290. }
  291. /**
  292. * 导出EXCEL时动态创建一个下拉列表
  293. * @param groupNamesList 数据集
  294. * @param firstRow 下拉框从第几行开始,默认最终行结束
  295. * @param firstCol 下拉框从第几列开始
  296. * @param fis 输入流
  297. * @param bos 输出流
  298. * @return 输出流
  299. */
  300. public static ByteArrayOutputStream createListBox(String[] groupNamesList,int firstRow,int firstCol,FileInputStream fis,ByteArrayOutputStream bos){
  301. return ExportExcel.createListBox(groupNamesList,firstRow,firstCol,fis,bos);
  302. }
  303. /**
  304. * 处理重复的主键,只取第一条,把后面重复的主键都置空
  305. * @param list 原始集合
  306. * @param id 要置空的主键
  307. * @return 处理后的集合
  308. */
  309. public static List<LinkedHashMap<String,Object>> handleRepeatPrimaryKey(List<LinkedHashMap<String,Object>> list,String id){
  310. List<LinkedHashMap<String,Object>> itemList = new ArrayList<>();
  311. for(LinkedHashMap<String,Object> lhm : list){
  312. if(itemList.size() == 0){
  313. itemList.add(lhm);
  314. }else {
  315. ListIterator<LinkedHashMap<String,Object>> listIterator = itemList.listIterator();
  316. int count = 0;
  317. while(listIterator.hasNext()){
  318. LinkedHashMap<String,Object> linkedHashMap = listIterator.next();
  319. if(StringUtils.isNotBlank(MapUtils.getString(linkedHashMap,id))){
  320. if(MapUtils.getString(linkedHashMap,id).equals(MapUtils.getString(lhm,id))){
  321. lhm.put(id,"");
  322. count ++;
  323. }
  324. }
  325. }
  326. if(count == 0){
  327. listIterator.add(lhm);
  328. }
  329. }
  330. }
  331. return list;
  332. }
  333. public static void main(String[] args) throws Exception {
  334. // 获取解析后的数据
  335. List<LinkedHashMap<String,Object>> parseData = parseData("D:\\DC\\impExcel\\2019\\7\\26\\fa9b5b0725fc400d8a6fdcab6427208a.xls",2,PblmFieldFormatImp.class);
  336. // 获取展示到前台的数据
  337. List<LinkedHashMap<String, Object>> showData = showData(parseData, PblmFieldFormatExp.class);
  338. System.out.println(showData);
  339. handleRepeatPrimaryKey(parseData,"pblmId");
  340. List<LinkedHashMap<String, Object>> list1 = parseData.stream().filter(x -> "".equals(x.get("pblmId").toString())).collect(Collectors.toList());
  341. List<LinkedHashMap<String, Object>> list2 = parseData.stream().filter(x -> !"".equals(x.get("pblmId").toString())).collect(Collectors.toList());
  342. System.out.println(list1);
  343. System.out.println(list2);
  344. }
  345. }