AbstractExcelParser.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. package com.iden.common.exceltool;
  2. import com.iden.common.util.SpringContextHolder;
  3. import lombok.extern.slf4j.Slf4j;
  4. import org.apache.poi.ss.formula.eval.ErrorEval;
  5. import org.apache.poi.ss.usermodel.*;
  6. import org.springframework.util.StringUtils;
  7. import java.io.IOException;
  8. import java.math.BigDecimal;
  9. import java.text.DecimalFormat;
  10. import java.text.SimpleDateFormat;
  11. import java.util.*;
  12. /**
  13. * @ProjectName: zdkj
  14. * @Package: com.zdkj.subway.st.exceltools
  15. * @ClassName: AbstractExcelParser
  16. * @Description:
  17. * @Author: kangjian
  18. * @CreateDate: 2020/1/12 9:32
  19. * @Version: 1.0
  20. */
  21. @Slf4j
  22. public class AbstractExcelParser {
  23. //起始行,默认从第一行开始
  24. protected int firstRowNum = 0;
  25. //定义数据总行数减去的行数
  26. protected int reduceRowNum = 0;
  27. protected Map<String, FormatType> formatColMap = new Hashtable<>();
  28. public static enum FormatType {
  29. ReplaceLineToDot
  30. }
  31. /**
  32. * 获取Excel的列头
  33. *
  34. * @param sheet
  35. * @return
  36. */
  37. protected List<String> getColumnHeader(Sheet sheet) {
  38. // 定义首行
  39. Row headerRow = null;
  40. // 定义列数
  41. int cellCount = 0;
  42. // 获取sheet的首行 并且 行的列数少于4列 或者 4列中有任意一列为空值,跳过不算为表头
  43. for (; firstRowNum < sheet.getLastRowNum(); firstRowNum++) {
  44. headerRow = sheet.getRow(firstRowNum);
  45. if (headerRow == null) {
  46. continue;
  47. }
  48. // 设置列数
  49. cellCount = headerRow.getLastCellNum();
  50. if (cellCount < 2) {
  51. continue;
  52. } else {
  53. if (headerRow.getCell(0) == null || headerRow.getCell(0).toString() == ""||headerRow.getCell(cellCount-1) == null || headerRow.getCell(cellCount-1).toString() == "") {
  54. continue;
  55. } else {
  56. break;
  57. }
  58. }
  59. }
  60. if (headerRow == null) {
  61. return null;
  62. }
  63. // 生成列
  64. List<String> headers = new ArrayList<>();
  65. for (int hi = headerRow.getFirstCellNum(); hi < cellCount; hi++) {
  66. String header = headerRow.getCell(hi).toString();
  67. if (!header.equals("")) {
  68. headers.add(header);
  69. }
  70. }
  71. return headers;
  72. }
  73. /**
  74. * 功能描述:
  75. *
  76. * @param sheet
  77. * @return: java.util.List<java.lang.String>
  78. * @exception:获取标题行,去掉标题行中的空白字符
  79. * @author: cqa
  80. * @date: 2019/4/15 15:50
  81. */
  82. protected List<String> getColumnHeaderWithoutBlank(Sheet sheet) {
  83. // 定义首行
  84. Row headerRow = null;
  85. // 定义列数
  86. int cellCount = 0;
  87. // 获取sheet的首行 并且 行的列数少于4列 或者 4列中有任意一列为空值,跳过不算为表头
  88. for (; firstRowNum < sheet.getLastRowNum(); firstRowNum++) {
  89. headerRow = sheet.getRow(firstRowNum);
  90. if (headerRow == null) {
  91. continue;
  92. }
  93. // 设置列数
  94. cellCount = headerRow.getLastCellNum();
  95. if (cellCount < 2) {
  96. continue;
  97. } else {
  98. if (headerRow.getCell(0) == null || headerRow.getCell(0).toString() == "") {
  99. continue;
  100. } else {
  101. break;
  102. }
  103. }
  104. }
  105. if (headerRow == null) {
  106. return null;
  107. }
  108. // 生成列
  109. List<String> headers = new ArrayList<String>();
  110. for (int hi = headerRow.getFirstCellNum(); hi < cellCount; hi++) {
  111. String header = headerRow.getCell(hi).getStringCellValue().replaceAll("\\s+", "");
  112. if (!header.equals("")) {
  113. headers.add(header);
  114. }
  115. }
  116. return headers;
  117. }
  118. protected String convertVal(Cell cell) {
  119. String cellValue = "";
  120. DataFormatter _formatter = new DataFormatter();
  121. if (cell != null) {
  122. switch (cell.getCellType()) {
  123. case Cell.CELL_TYPE_STRING:
  124. cellValue = cell.getRichStringCellValue().getString().trim();
  125. break;
  126. case Cell.CELL_TYPE_NUMERIC:
  127. double contentNumber = cell.getNumericCellValue();
  128. if (contentNumber - (int) contentNumber < Double.MIN_VALUE) { // 是否为int型
  129. cellValue = Integer.toString((int) contentNumber);
  130. } else {// 是否为double型
  131. cellValue = getnumberCell(cell);
  132. }
  133. //日期
  134. if (DateUtil.isCellDateFormatted(cell)) {
  135. Date theDate = cell.getDateCellValue();
  136. SimpleDateFormat dff = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  137. cellValue = dff.format(theDate);
  138. }
  139. break;
  140. case Cell.CELL_TYPE_BOOLEAN:
  141. cellValue = String.valueOf(cell.getBooleanCellValue()).trim();
  142. break;
  143. case Cell.CELL_TYPE_FORMULA:// 公式
  144. switch (cell.getCachedFormulaResultType()) {
  145. case Cell.CELL_TYPE_STRING:
  146. RichTextString str = cell.getRichStringCellValue();
  147. if (str != null && str.length() > 0) {
  148. return str.toString();
  149. }
  150. case Cell.CELL_TYPE_NUMERIC:
  151. CellStyle style = cell.getCellStyle();
  152. if (style == null) {
  153. return cell.getNumericCellValue() + "";// double转成String
  154. } else {
  155. return _formatter.formatRawCellContents(cell.getNumericCellValue(), style.getDataFormat(), style.getDataFormatString());
  156. }
  157. case Cell.CELL_TYPE_BOOLEAN:
  158. return cell.getBooleanCellValue() ? "true" : "false";// boolean
  159. // 转成String
  160. case Cell.CELL_TYPE_ERROR:
  161. return ErrorEval.getText(cell.getErrorCellValue());
  162. }
  163. default:
  164. cellValue = "";
  165. }
  166. }
  167. return cellValue;
  168. }
  169. /**
  170. * 公共的导入excel方法
  171. *
  172. * @param sheet 文件
  173. * @param obj 实体类
  174. * @return
  175. * @throws IOException
  176. */
  177. public <T> List<T> importBaseExcel(Sheet sheet, T obj){
  178. List<T> result = new ArrayList<>();
  179. try {
  180. //缓存
  181. List<ColInfo> headertocolumn = ExcelUtil.getBeanColbyOder(obj);
  182. //读取文件内容
  183. Workbook workbook = sheet.getWorkbook();
  184. // //获取工作表
  185. // Sheet sheet = workbook.getSheet(sheetname);
  186. List<String> headers = this.getColumnHeader(sheet);
  187. FormulaEvaluator ife = workbook.getCreationHelper()
  188. .createFormulaEvaluator();
  189. // 最后一列的标号 即总的行数
  190. int ri = firstRowNum + 1;
  191. // 定义列数
  192. int cellCount = 0;
  193. cellCount = headers.size();
  194. String classname = obj.getClass().getName();
  195. Class<?> clazz = Class.forName(classname);
  196. // 循环table赋值
  197. for (; ri <= sheet.getLastRowNum() - reduceRowNum; ri++)// 循环行 (使用小于等于 <= 否则最后一行读不到)
  198. {
  199. Row row = sheet.getRow(ri);
  200. if (row == null) {
  201. continue;
  202. }
  203. //可以根据该类名生成Java对象
  204. T tmp = (T) clazz.newInstance();
  205. Map<String, String> rowData = new Hashtable<String, String>();
  206. //记录空行,如果val==""则为空行
  207. //可以根据该类名生成Java对象
  208. for (int rj = row.getFirstCellNum(); rj < cellCount; rj++)// 循环列
  209. {
  210. Cell cell = row.getCell(rj);
  211. if (cell != null
  212. && cell.getCellStyle().toString().toUpperCase() == "FORMULA") {
  213. ife.evaluateInCell(cell);// 加一列计算,如果该列使用了公式或者D2+F2*1000-1
  214. // 这种自定义算法, 就需要取值而不是取文本
  215. }
  216. String headername = headers.get(rj).trim();
  217. //获取
  218. String column = getcolname(headertocolumn,headername);
  219. if (column != null) {
  220. String colhandlebysql=getcolsbysql(headertocolumn,column);
  221. String value = getCellValue(cell);
  222. //判断Excel导入列,如果需要sql转换
  223. if(!StringUtils.isEmpty(colhandlebysql)){
  224. value=convertValBysql(colhandlebysql,value);
  225. }
  226. ExcelUtil.setFileValue(tmp,value,column);
  227. }
  228. }
  229. result.add(tmp);
  230. }
  231. } catch (Exception e) {
  232. log.error("Excel导入异常:", e);
  233. }
  234. return result;
  235. }
  236. /**
  237. * 处理sql值转换
  238. * @param colhandlebysql
  239. * @param value
  240. * @return
  241. */
  242. private String convertValBysql(String colhandlebysql, String value) {
  243. DbHelper dbHelper= SpringContextHolder.getBean(DbHelper.class);
  244. String result=dbHelper.selectByExceltools(colhandlebysql,value);
  245. return result;
  246. }
  247. /**
  248. * 特殊列需要转换的列,进行sql获取
  249. * @param colInfos
  250. * @param column
  251. * @return
  252. */
  253. private String getcolsbysql(List<ColInfo> colInfos, String column) {
  254. String sql="";
  255. for(ColInfo colInfo:colInfos)
  256. {
  257. if(colInfo.getColname().equals(column))
  258. {
  259. sql=colInfo.getColhandlebysql();
  260. break;
  261. }
  262. }
  263. return sql;
  264. }
  265. /**
  266. * 格式化转换Excel
  267. *
  268. * @param cell
  269. * @return
  270. */
  271. private String getCellValue(Cell cell) {
  272. String val = "";
  273. if (cell != null) {
  274. val = replaceContent(convertVal(cell));
  275. }
  276. return val;
  277. }
  278. /**
  279. * 根据列集合返回字段名称
  280. * @param colInfos
  281. * @param displayname
  282. * @return
  283. */
  284. private String getcolname(List<ColInfo> colInfos,String displayname){
  285. String colname="";
  286. for(ColInfo colInfo:colInfos)
  287. {
  288. if(colInfo.getDisplayname().equals(displayname))
  289. {
  290. colname=colInfo.getColname();
  291. break;
  292. }
  293. }
  294. return colname;
  295. }
  296. /**
  297. * 将其它分隔符替换为半角逗号。如:、,;;
  298. *
  299. * @param content 要替换的内容
  300. * @return
  301. */
  302. protected String replaceContent(String content) {
  303. if (content.equals("")) {
  304. return "";
  305. }
  306. content = content.trim();
  307. content = content.replace("–", "-");
  308. content = content.replace("-", "-");
  309. content = content.replace(":", ":");
  310. content = content.replace("、", ",");
  311. content = content.replace(",", ",");
  312. content = content.replace(", ,", ",");
  313. content = content.replace(';', ',');
  314. content = content.replace("\r\n", ",");
  315. content = content.replace("\n", ",");
  316. content = content.replace(';', ',');
  317. content = content.replace("?", "");
  318. content = content.replace("  ", "");
  319. content = content.replace("?", "");
  320. content = content.replace(" ", "");
  321. content = content.endsWith(",") ? content.substring(0,
  322. content.length() - 1) : content;
  323. return content;
  324. }
  325. protected String getnumberCell(Cell cell) {
  326. String content = (new BigDecimal(String.valueOf(cell.getNumericCellValue()))).toString();
  327. if (content.toUpperCase().contains("E")) {
  328. DecimalFormat df = new DecimalFormat("0");
  329. content = df.format(cell.getNumericCellValue());
  330. }
  331. return content;
  332. }
  333. }