POIExcelToHtml.java 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. package com.steerinfo.dil.util;
  2. import org.apache.poi.hssf.usermodel.*;
  3. import org.apache.poi.hssf.util.HSSFColor;
  4. import org.apache.poi.ss.usermodel.*;
  5. import org.apache.poi.ss.util.CellRangeAddress;
  6. import org.apache.poi.xssf.usermodel.XSSFCellStyle;
  7. import org.apache.poi.xssf.usermodel.XSSFColor;
  8. import org.apache.poi.xssf.usermodel.XSSFFont;
  9. import org.apache.poi.xssf.usermodel.XSSFWorkbook;
  10. import java.io.IOException;
  11. import java.io.InputStream;
  12. import java.text.DecimalFormat;
  13. import java.text.SimpleDateFormat;
  14. import java.util.Date;
  15. import java.util.HashMap;
  16. import java.util.Map;
  17. /**
  18. * POIExcelToHtml 文件转换:
  19. *
  20. * @author generator
  21. * @version 1.0-SNAPSHORT 2021-08-09 18:06
  22. * 类描述
  23. * 修订历史:
  24. * 日期:2021-08-09
  25. * 作者:shadow
  26. * 参考:
  27. * 描述:Execl转HTML
  28. * @Copyright 湖南视拓信息技术股份有限公司. All rights reserved.
  29. * @see null
  30. */
  31. public class POIExcelToHtml {
  32. public static String excelToHtml(InputStream is) {
  33. String htmlExcel = "预览文件失败";
  34. try {
  35. Workbook wb = WorkbookFactory.create(is);
  36. if (wb instanceof XSSFWorkbook) {
  37. XSSFWorkbook xWb = (XSSFWorkbook) wb;
  38. htmlExcel = POIExcelToHtml.getExcelInfo(xWb);
  39. } else if (wb instanceof HSSFWorkbook) {
  40. HSSFWorkbook hWb = (HSSFWorkbook) wb;
  41. htmlExcel = POIExcelToHtml.getExcelInfo(hWb);
  42. }
  43. } catch (Exception e) {
  44. e.printStackTrace();
  45. } finally {
  46. try {
  47. is.close();
  48. } catch (IOException e) {
  49. e.printStackTrace();
  50. }
  51. }
  52. return htmlExcel;
  53. }
  54. private static String getExcelInfo(Workbook wb) {
  55. StringBuffer sb = new StringBuffer();
  56. int sheetCounts = wb.getNumberOfSheets();
  57. // sb.append("<!DOCTYPE html> <html> <head> <meta charset='utf-8'
  58. // /><title>HTML实例</title></head> ");
  59. for (int i = 0; i < sheetCounts; i++) {
  60. Sheet sheet = wb.getSheetAt(i);// 获取第一个Sheet的内容
  61. int lastRowNum = sheet.getLastRowNum();
  62. Map<String, String> map[] = getRowSpanColSpanMap(sheet);
  63. // sb.append("<br><br>");
  64. sb.append(sheet.getSheetName());
  65. sb.append("<table style='border-collapse:collapse;' width='100%'>");
  66. Row row = null; // 兼容
  67. Cell cell = null; // 兼容
  68. for (int rowNum = sheet.getFirstRowNum(); rowNum <= lastRowNum; rowNum++) {
  69. row = sheet.getRow(rowNum);
  70. if (row == null) {
  71. sb.append("<tr><td > &nbsp;</td></tr>");
  72. continue;
  73. }
  74. sb.append("<tr>");
  75. int lastColNum = row.getLastCellNum();
  76. for (int colNum = 0; colNum < lastColNum; colNum++) {
  77. cell = row.getCell(colNum);
  78. if (cell == null) { // 特殊情况 空白的单元格会返回null
  79. sb.append("<td>&nbsp;</td>");
  80. continue;
  81. }
  82. String stringValue = getCellValue(cell);//````````````
  83. if (map[0].containsKey(rowNum + "," + colNum)) {
  84. String pointString = map[0].get(rowNum + "," + colNum);
  85. map[0].remove(rowNum + "," + colNum);
  86. int bottomeRow = Integer.valueOf(pointString.split(",")[0]);
  87. int bottomeCol = Integer.valueOf(pointString.split(",")[1]);
  88. int rowSpan = bottomeRow - rowNum + 1;
  89. int colSpan = bottomeCol - colNum + 1;
  90. sb.append("<td rowspan= '" + rowSpan + "' colspan= '" + colSpan + "' ");
  91. } else if (map[1].containsKey(rowNum + "," + colNum)) {
  92. map[1].remove(rowNum + "," + colNum);
  93. continue;
  94. } else {
  95. sb.append("<td ");
  96. }
  97. dealExcelStyle(wb, sheet, cell, sb);// 处理单元格样式
  98. sb.append(">");
  99. if (stringValue == null || "".equals(stringValue.trim())) {
  100. sb.append(" &nbsp; ");
  101. } else {
  102. // 将ascii码为160的空格转换为html下的空格(&nbsp;)
  103. sb.append(stringValue.replace(String.valueOf((char) 160), "&nbsp;"));
  104. }
  105. sb.append("</td>");
  106. }
  107. sb.append("</tr>");
  108. }
  109. sb.append("</table>");
  110. }
  111. // sb.append("</body></html> ");
  112. return sb.toString();
  113. }
  114. private static Map<String, String>[] getRowSpanColSpanMap(Sheet sheet) {
  115. Map<String, String> map0 = new HashMap<String, String>();
  116. Map<String, String> map1 = new HashMap<String, String>();
  117. int mergedNum = sheet.getNumMergedRegions();
  118. CellRangeAddress range = null;
  119. for (int i = 0; i < mergedNum; i++) {
  120. range = sheet.getMergedRegion(i);
  121. int topRow = range.getFirstRow();
  122. int topCol = range.getFirstColumn();
  123. int bottomRow = range.getLastRow();
  124. int bottomCol = range.getLastColumn();
  125. map0.put(topRow + "," + topCol, bottomRow + "," + bottomCol);
  126. // System.out.println(topRow + "," + topCol + "," + bottomRow + ","
  127. // + bottomCol);
  128. int tempRow = topRow;
  129. while (tempRow <= bottomRow) {
  130. int tempCol = topCol;
  131. while (tempCol <= bottomCol) {
  132. map1.put(tempRow + "," + tempCol, "");
  133. tempCol++;
  134. }
  135. tempRow++;
  136. }
  137. map1.remove(topRow + "," + topCol);
  138. }
  139. Map[] map = {map0, map1};
  140. return map;
  141. }
  142. /**
  143. * 200 * 获取表格单元格Cell内容 201 * @param cell 202 * @return 203
  144. */
  145. private static String getCellValue(Cell cell) {
  146. String result = new String();
  147. switch (cell.getCellType()) {
  148. case Cell.CELL_TYPE_NUMERIC:// 数字类型
  149. if (HSSFDateUtil.isCellDateFormatted(cell)) {// 处理日期格式、时间格式
  150. SimpleDateFormat sdf = null;
  151. if (cell.getCellStyle().getDataFormat() == HSSFDataFormat.getBuiltinFormat("hh:mm")) {
  152. sdf = new SimpleDateFormat("HH:mm");
  153. } else if (cell.getCellStyle().getDataFormat() == HSSFDataFormat
  154. .getBuiltinFormat("yyyy-MM-dd HH:mm:ss")) {// 日期
  155. sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  156. } else {
  157. sdf = new SimpleDateFormat("yyyy-MM-dd");
  158. }
  159. Date date = cell.getDateCellValue();
  160. result = sdf.format(date);
  161. } else if (cell.getCellStyle().getDataFormat() == 58) {
  162. // 处理自定义日期格式:m月d日(通过判断单元格的格式id解决,id的值是58)
  163. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
  164. double value = cell.getNumericCellValue();
  165. Date date = DateUtil.getJavaDate(value);
  166. result = sdf.format(date);
  167. } else {
  168. double value = cell.getNumericCellValue();
  169. CellStyle style = cell.getCellStyle();
  170. DecimalFormat format = new DecimalFormat();
  171. String temp = style.getDataFormatString();
  172. // 单元格设置成常规
  173. if (temp.equals("General")) {
  174. format.applyPattern("#");
  175. }
  176. result = format.format(value);
  177. }
  178. break;
  179. case Cell.CELL_TYPE_STRING:// String类型
  180. result = cell.getRichStringCellValue().toString();
  181. break;
  182. case Cell.CELL_TYPE_BLANK:
  183. result = "";
  184. break;
  185. default:
  186. result = "";
  187. break;
  188. }
  189. return result;
  190. }
  191. /**
  192. * 251 * 处理表格样式 252 * @param wb 253 * @param sheet 254 * @param cell 255
  193. * * @param sb 256
  194. */
  195. private static void dealExcelStyle(Workbook wb, Sheet sheet, Cell cell, StringBuffer sb) {
  196. CellStyle cellStyle = cell.getCellStyle();
  197. if (cellStyle != null) {
  198. //short alignment = cellStyle.getAlignment();旧写法获取枚举数字;新写法获取枚举
  199. sb.append("align='" + convertAlignToHtml(cellStyle.getAlignmentEnum()) + "' ");// 单元格内容的水平对齐方式
  200. //short verticalAlignment = cellStyle.getVerticalAlignment();
  201. //short verticalAlignment = cellStyle.getVerticalAlignmentEnum().getCode();
  202. sb.append("valign='" + convertVerticalAlignToHtml(cellStyle.getVerticalAlignmentEnum()) + "' ");// 单元格中内容的垂直排列方式
  203. if (wb instanceof XSSFWorkbook) {
  204. XSSFFont xf = ((XSSFCellStyle) cellStyle).getFont();
  205. Boolean boldWeight = xf.getBold();
  206. //short boldWeight = xf.getBoldweight();
  207. String fontfamily = xf.getFontName();
  208. int underline = xf.getUnderline();
  209. boolean Italic = xf.getItalic();
  210. sb.append("style='");
  211. if (underline >= 1) {
  212. sb.append("text-decoration:underline;"); // 字体型号
  213. }
  214. if (Italic) {
  215. sb.append("font-style: italic;"); // 字体型号
  216. }
  217. sb.append("font-family:" + fontfamily + ";"); // 字体型号
  218. sb.append("font-weight:" + (boldWeight ? "bold" : "100") + ";"); // 字体加粗
  219. sb.append("font-size: " + xf.getFontHeight() / 2 + "%;"); // 字体大小
  220. int columnWidth = sheet.getColumnWidth(cell.getColumnIndex());
  221. sb.append("width:" + columnWidth + "px;");
  222. XSSFColor xc = xf.getXSSFColor();
  223. if (xc != null && !"".equals(xc)) {
  224. sb.append("color:#" + xc.getARGBHex().substring(2) + ";"); // 字体颜色
  225. }
  226. XSSFColor bgColor = (XSSFColor) cellStyle.getFillForegroundColorColor();
  227. if (bgColor != null && !"".equals(bgColor)) {
  228. sb.append("background-color:#" + bgColor.getARGBHex().substring(2) + ";"); // 背景颜色
  229. }
  230. sb.append(getBorderStyle(0, cellStyle.getBorderTop(),
  231. ((XSSFCellStyle) cellStyle).getTopBorderXSSFColor()));
  232. sb.append(getBorderStyle(1, cellStyle.getBorderRight(),
  233. ((XSSFCellStyle) cellStyle).getRightBorderXSSFColor()));
  234. sb.append(getBorderStyle(2, cellStyle.getBorderBottom(),
  235. ((XSSFCellStyle) cellStyle).getBottomBorderXSSFColor()));
  236. sb.append(getBorderStyle(3, cellStyle.getBorderLeft(),
  237. ((XSSFCellStyle) cellStyle).getLeftBorderXSSFColor()));
  238. } else if (wb instanceof HSSFWorkbook) {
  239. HSSFFont hf = ((HSSFCellStyle) cellStyle).getFont(wb);
  240. short fontColor = hf.getColor();
  241. Boolean boldWeight = hf.getBold();
  242. //short boldWeight = hf.getBoldweight();
  243. String fontfamily = hf.getFontName();
  244. int underline = hf.getUnderline();
  245. boolean Italic = hf.getItalic();
  246. sb.append("style='");
  247. if (underline >= 1) {
  248. // 字体型号
  249. sb.append("text-decoration:underline;");
  250. }
  251. if (Italic) {
  252. // 字体型号
  253. sb.append("font-style: italic;");
  254. }
  255. // 类HSSFPalette用于求的颜色的国际标准形式
  256. HSSFPalette palette = ((HSSFWorkbook) wb).getCustomPalette();
  257. HSSFColor hc = palette.getColor(fontColor);
  258. // 字体加粗
  259. sb.append("font-weight:" + (boldWeight ? "bold" : "100") + ";");
  260. // 字体型号
  261. sb.append("font-family:" + fontfamily + ";");
  262. // 字体大小
  263. sb.append("font-size: " + hf.getFontHeight() / 2 + "%;");
  264. String fontColorStr = convertToStardColor(hc);
  265. // 字体颜色
  266. if (fontColorStr != null && !"".equals(fontColorStr.trim())) {
  267. sb.append("color:" + fontColorStr + ";");
  268. }
  269. int columnWidth = sheet.getColumnWidth(cell.getColumnIndex());
  270. sb.append("width:" + columnWidth + "px;");
  271. short bgColor = cellStyle.getFillForegroundColor();
  272. //short bgColor = cellStyle.getFillBackgroundColor();
  273. hc = palette.getColor(bgColor);
  274. String bgColorStr = convertToStardColor(hc);
  275. if (bgColorStr != null && !"".equals(bgColorStr.trim())) {
  276. // 背景颜色
  277. sb.append("background-color:" + bgColorStr + ";");
  278. }
  279. /**
  280. * 旧版本 cellStyle.getBorderTop()
  281. * 新版本 cellStyle.getBorderTopEnum()
  282. */
  283. sb.append(getBorderStyle(palette, 0, cellStyle.getBorderTop(), cellStyle.getTopBorderColor()));
  284. sb.append(getBorderStyle(palette, 1, cellStyle.getBorderRight(), cellStyle.getRightBorderColor()));
  285. sb.append(getBorderStyle(palette, 3, cellStyle.getBorderLeft(), cellStyle.getLeftBorderColor()));
  286. sb.append(getBorderStyle(palette, 2, cellStyle.getBorderBottom(), cellStyle.getBottomBorderColor()));
  287. }
  288. sb.append("' ");
  289. }
  290. }
  291. /**
  292. * 330 * 单元格内容的水平对齐方式 331 * @param alignment 332 * @return 333
  293. *
  294. * @param alignment
  295. */
  296. private static String convertAlignToHtml(HorizontalAlignment alignment) {
  297. String align = "left";
  298. /**
  299. * CellStyle.ALIGN_CENTER:旧写法
  300. * HorizontalAlignment.LEFT:新写法
  301. */
  302. switch (alignment) {
  303. case LEFT:
  304. align = "left";
  305. break;
  306. case CENTER:
  307. align = "center";
  308. break;
  309. case RIGHT:
  310. align = "right";
  311. break;
  312. default:
  313. break;
  314. }
  315. return align;
  316. }
  317. /**
  318. * 354 * 单元格中内容的垂直排列方式 355 * @param verticalAlignment 356 * @return 357
  319. *
  320. * @param verticalAlignment
  321. */
  322. private static String convertVerticalAlignToHtml(VerticalAlignment verticalAlignment) {
  323. /**
  324. * 旧写法CellStyle.VERTICAL_BOTTOM:
  325. * 新写法VerticalAlignment.BOTTOM:
  326. */
  327. String valign = "middle";
  328. switch (verticalAlignment) {
  329. case BOTTOM:
  330. valign = "bottom";
  331. break;
  332. case CENTER:
  333. valign = "center";
  334. break;
  335. case TOP:
  336. valign = "top";
  337. break;
  338. default:
  339. break;
  340. }
  341. return valign;
  342. }
  343. private static String convertToStardColor(HSSFColor hc) {
  344. /**
  345. * 颜色定义变化
  346. * 旧版本 : HSSFColor.BLACK.index
  347. * 新版本 : IndexedColors.BLACK.index
  348. */
  349. StringBuffer sb = new StringBuffer("");
  350. if (hc != null) {
  351. if (IndexedColors.AUTOMATIC.index == hc.getIndex()) {
  352. return null;
  353. }
  354. sb.append("#");
  355. for (int i = 0; i < hc.getTriplet().length; i++) {
  356. sb.append(fillWithZero(Integer.toHexString(hc.getTriplet()[i])));
  357. }
  358. }
  359. return sb.toString();
  360. }
  361. private static String fillWithZero(String str) {
  362. if (str != null && str.length() < 2) {
  363. return "0" + str;
  364. }
  365. return str;
  366. }
  367. static String[] bordesr = {"border-top:", "border-right:", "border-bottom:", "border-left:"};
  368. static String[] borderStyles = {"solid ", "solid ", "solid ", "solid ", "solid ", "solid ", "solid ", "solid ",
  369. "solid ", "solid", "solid", "solid", "solid", "solid"};
  370. private static String getBorderStyle(HSSFPalette palette, int b, short s, short t) {
  371. if (s == 0) {
  372. return bordesr[b] + borderStyles[s] + "#d0d7e5 1px;";
  373. }
  374. String borderColorStr = convertToStardColor(palette.getColor(t));
  375. borderColorStr = borderColorStr == null || borderColorStr.length() < 1 ? "#000000" : borderColorStr;
  376. return bordesr[b] + borderStyles[s] + borderColorStr + " 1px;";
  377. }
  378. private static String getBorderStyle(int b, short s, XSSFColor xc) {
  379. if (s == 0) {
  380. return bordesr[b] + borderStyles[s] + "#d0d7e5 1px;";
  381. }
  382. if (xc != null && !"".equals(xc)) {
  383. // t.getARGBHex();
  384. String borderColorStr = xc.getARGBHex();
  385. borderColorStr = borderColorStr == null || borderColorStr.length() < 1 ? "#000000"
  386. : borderColorStr.substring(2);
  387. return bordesr[b] + borderStyles[s] + borderColorStr + " 1px;";
  388. }
  389. return "";
  390. }
  391. }