1. package com.sun.office.excel;
  2.  
  3. /**
  4. * 跨行元素元数据
  5. *
  6. */
  7. public class CrossRangeCellMeta {
  8.  
  9. public CrossRangeCellMeta(int firstRowIndex, int firstColIndex, int rowSpan, int colSpan) {
  10. super();
  11. this.firstRowIndex = firstRowIndex;
  12. this.firstColIndex = firstColIndex;
  13. this.rowSpan = rowSpan;
  14. this.colSpan = colSpan;
  15. }
  16.  
  17. private int firstRowIndex;
  18. private int firstColIndex;
  19. private int rowSpan;// 跨越行数
  20. private int colSpan;// 跨越列数
  21.  
  22. int getFirstRow() {
  23. return firstRowIndex;
  24. }
  25.  
  26. int getLastRow() {
  27. return firstRowIndex + rowSpan - 1;
  28. }
  29.  
  30. int getFirstCol() {
  31. return firstColIndex;
  32. }
  33.  
  34. int getLastCol() {
  35. return firstColIndex + colSpan - 1;
  36. }
  37.  
  38. int getColSpan(){
  39. return colSpan;
  40. }
  41. }
  1. package com.sun.office.excel;
  2.  
  3. import java.io.File;
  4. import java.io.FileInputStream;
  5. import java.io.FileOutputStream;
  6. import java.util.ArrayList;
  7. import java.util.List;
  8.  
  9. import org.apache.commons.lang3.StringUtils;
  10. import org.apache.commons.lang3.math.NumberUtils;
  11. import org.apache.poi.hssf.usermodel.HSSFCell;
  12. import org.apache.poi.hssf.usermodel.HSSFCellStyle;
  13. import org.apache.poi.hssf.usermodel.HSSFFont;
  14. import org.apache.poi.hssf.usermodel.HSSFRow;
  15. import org.apache.poi.hssf.usermodel.HSSFSheet;
  16. import org.apache.poi.hssf.usermodel.HSSFWorkbook;
  17. import org.apache.poi.hssf.util.HSSFColor;
  18. import org.apache.poi.ss.util.CellRangeAddress;
  19. import org.dom4j.Document;
  20. import org.dom4j.DocumentException;
  21. import org.dom4j.DocumentHelper;
  22. import org.dom4j.Element;
  23.  
  24. /**
  25. * 将html table 转成 excel
  26. *
  27. * 记录下来所占的行和列,然后填充合并
  28. */
  29. public class ConvertHtml2Excel {
  30. public static void main(String[] args) {
  31. byte[] bs = null;
  32. try {
  33. FileInputStream fis = new FileInputStream(new File(ConvertHtml2Excel.class.getResource("./a.html").getPath()));
  34. bs = new byte[fis.available()];
  35. fis.read(bs);
  36. fis.close();
  37. } catch (Exception e1) {
  38. e1.printStackTrace();
  39. }
  40. String c = new String(bs);
  41. HSSFWorkbook wb = table2Excel(c);
  42. try {
  43. FileOutputStream fos = new FileOutputStream(new File("1.xls"));
  44. wb.write(fos);
  45. fos.flush();
  46. fos.close();
  47. } catch (Exception e) {
  48. // TODO Auto-generated catch block
  49. e.printStackTrace();
  50. }
  51.  
  52. }
  53.  
  54. /**
  55. * html表格转excel
  56. *
  57. * @param tableHtml 如
  58. * <table>
  59. * ..
  60. * </table>
  61. * @return
  62. */
  63. public static HSSFWorkbook table2Excel(String tableHtml) {
  64. HSSFWorkbook wb = new HSSFWorkbook();
  65. HSSFSheet sheet = wb.createSheet();
  66. List<CrossRangeCellMeta> crossRowEleMetaLs = new ArrayList<CrossRangeCellMeta>();
  67. int rowIndex = 0;
  68. try {
  69. Document data = DocumentHelper.parseText(tableHtml);
  70. // 生成表头
  71. Element thead = data.getRootElement().element("thead");
  72. HSSFCellStyle titleStyle = getTitleStyle(wb);
  73. if (thead != null) {
  74. List<Element> trLs = thead.elements("tr");
  75. for (Element trEle : trLs) {
  76. HSSFRow row = sheet.createRow(rowIndex);
  77. List<Element> thLs = trEle.elements("th");
  78. makeRowCell(thLs, rowIndex, row, 0, titleStyle, crossRowEleMetaLs);
  79. rowIndex++;
  80. }
  81. }
  82. // 生成表体
  83. Element tbody = data.getRootElement().element("tbody");
  84. if (tbody != null) {
  85. HSSFCellStyle contentStyle = getContentStyle(wb);
  86. List<Element> trLs = tbody.elements("tr");
  87. for (Element trEle : trLs) {
  88. HSSFRow row = sheet.createRow(rowIndex);
  89. List<Element> thLs = trEle.elements("th");
  90. int cellIndex = makeRowCell(thLs, rowIndex, row, 0, titleStyle, crossRowEleMetaLs);
  91. List<Element> tdLs = trEle.elements("td");
  92. makeRowCell(tdLs, rowIndex, row, cellIndex, contentStyle, crossRowEleMetaLs);
  93. rowIndex++;
  94. }
  95. }
  96. // 合并表头
  97. for (CrossRangeCellMeta crcm : crossRowEleMetaLs) {
  98. sheet.addMergedRegion(new CellRangeAddress(crcm.getFirstRow(), crcm.getLastRow(), crcm.getFirstCol(), crcm.getLastCol()));
  99. }
  100. } catch (DocumentException e) {
  101. e.printStackTrace();
  102. }
  103.  
  104. return wb;
  105. }
  106.  
  107. /**
  108. * 生产行内容
  109. *
  110. * @return 最后一列的cell index
  111. */
  112. /**
  113. * @param tdLs th或者td集合
  114. * @param rowIndex 行号
  115. * @param row POI行对象
  116. * @param startCellIndex
  117. * @param cellStyle 样式
  118. * @param crossRowEleMetaLs 跨行元数据集合
  119. * @return
  120. */
  121. private static int makeRowCell(List<Element> tdLs, int rowIndex, HSSFRow row, int startCellIndex, HSSFCellStyle cellStyle,
  122. List<CrossRangeCellMeta> crossRowEleMetaLs) {
  123. int i = startCellIndex;
  124. for (int eleIndex = 0; eleIndex < tdLs.size(); i++, eleIndex++) {
  125. int captureCellSize = getCaptureCellSize(rowIndex, i, crossRowEleMetaLs);
  126. while (captureCellSize > 0) {
  127. for (int j = 0; j < captureCellSize; j++) {// 当前行跨列处理(补单元格)
  128. row.createCell(i);
  129. i++;
  130. }
  131. captureCellSize = getCaptureCellSize(rowIndex, i, crossRowEleMetaLs);
  132. }
  133. Element thEle = tdLs.get(eleIndex);
  134. String val = thEle.getTextTrim();
  135. if (StringUtils.isBlank(val)) {
  136. Element e = thEle.element("a");
  137. if (e != null) {
  138. val = e.getTextTrim();
  139. }
  140. }
  141. HSSFCell c = row.createCell(i);
  142. if (NumberUtils.isNumber(val)) {
  143. c.setCellValue(Double.parseDouble(val));
  144. c.setCellType(HSSFCell.CELL_TYPE_NUMERIC);
  145. } else {
  146. c.setCellValue(val);
  147. }
  148. c.setCellStyle(cellStyle);
  149. int rowSpan = NumberUtils.toInt(thEle.attributeValue("rowspan"), 1);
  150. int colSpan = NumberUtils.toInt(thEle.attributeValue("colspan"), 1);
  151. if (rowSpan > 1 || colSpan > 1) { // 存在跨行或跨列
  152. crossRowEleMetaLs.add(new CrossRangeCellMeta(rowIndex, i, rowSpan, colSpan));
  153. }
  154. if (colSpan > 1) {// 当前行跨列处理(补单元格)
  155. for (int j = 1; j < colSpan; j++) {
  156. i++;
  157. row.createCell(i);
  158. }
  159. }
  160. }
  161. return i;
  162. }
  163.  
  164. /**
  165. * 获得因rowSpan占据的单元格
  166. *
  167. * @param rowIndex 行号
  168. * @param colIndex 列号
  169. * @param crossRowEleMetaLs 跨行列元数据
  170. * @return 当前行在某列需要占据单元格
  171. */
  172. private static int getCaptureCellSize(int rowIndex, int colIndex, List<CrossRangeCellMeta> crossRowEleMetaLs) {
  173. int captureCellSize = 0;
  174. for (CrossRangeCellMeta crossRangeCellMeta : crossRowEleMetaLs) {
  175. if (crossRangeCellMeta.getFirstRow() < rowIndex && crossRangeCellMeta.getLastRow() >= rowIndex) {
  176. if (crossRangeCellMeta.getFirstCol() <= colIndex && crossRangeCellMeta.getLastCol() >= colIndex) {
  177. captureCellSize = crossRangeCellMeta.getLastCol() - colIndex + 1;
  178. }
  179. }
  180. }
  181. return captureCellSize;
  182. }
  183.  
  184. /**
  185. * 获得标题样式
  186. *
  187. * @param workbook
  188. * @return
  189. */
  190. private static HSSFCellStyle getTitleStyle(HSSFWorkbook workbook) {
  191. short titlebackgroundcolor = HSSFColor.GREY_25_PERCENT.index;
  192. short fontSize = 12;
  193. String fontName = "宋体";
  194. HSSFCellStyle style = workbook.createCellStyle();
  195. style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
  196. style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
  197. style.setBorderBottom((short) 1);
  198. style.setBorderTop((short) 1);
  199. style.setBorderLeft((short) 1);
  200. style.setBorderRight((short) 1);
  201. style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
  202. style.setFillForegroundColor(titlebackgroundcolor);// 背景色
  203.  
  204. HSSFFont font = workbook.createFont();
  205. font.setFontName(fontName);
  206. font.setFontHeightInPoints(fontSize);
  207. font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
  208. style.setFont(font);
  209. return style;
  210. }
  211.  
  212. /**
  213. * 获得内容样式
  214. *
  215. * @param wb
  216. * @return
  217. */
  218. private static HSSFCellStyle getContentStyle(HSSFWorkbook wb) {
  219. short fontSize = 12;
  220. String fontName = "宋体";
  221. HSSFCellStyle style = wb.createCellStyle();
  222. style.setBorderBottom((short) 1);
  223. style.setBorderTop((short) 1);
  224. style.setBorderLeft((short) 1);
  225. style.setBorderRight((short) 1);
  226.  
  227. HSSFFont font = wb.createFont();
  228. font.setFontName(fontName);
  229. font.setFontHeightInPoints(fontSize);
  230. style.setFont(font);
  231. return style;
  232. }
  233. }

基本思路:

  逐行遍历,记录下单元格所占的行和列,根据行列去填充空格,合并单元格

将html table 转成 excel的更多相关文章

  1. MVC 将视图页table导出成excel

    前台代码: <table class="tablelist" id="myTable">    <thead>        <t ...

  2. js实现把网页table导成Excel

    //导出excel function exportExcel(DivID,strTitle){ if(DivID==null) { return false; } var jXls, myWorkbo ...

  3. js实现把网页table导成Excel(bootstrap、JqGrid、Json)

    方案一:支持IE //导出excel function exportExcel(DivID,strTitle){ if(DivID==null) { return false; } var jXls, ...

  4. js中的table导出成Excel表格

    首先判断手否是IE,原因在于IE导出我用的是ActiveXObject,判断的方式很简单,只需要拿到window.navigator.userAgent即可进行判断,代码如下 function get ...

  5. C#将html table 导出成excel实例

    public void ProcessRequest (HttpContext context) { string elxStr = "<table><tbody>& ...

  6. 前端Table数据导出Excel使用HSSFWorkbook(Java)

    一.实现原理: 1. 前端查询列表数据并渲染至table(<table>...</table>)表格 2. 表格html代码传输至后台 3. 后台把html转成Excel输出流 ...

  7. web利用table表格生成excel格式问题

    当我们把web页面上的table导成excel形式时,有时候我们的数据需要以特定的格式呈现出来,这时候我们就需要给指定的单元格添加一些样式规格信息. 文本:vnd.ms-excel.numberfor ...

  8. Html Table用JS导出excel格式问题 导出EXCEL后单元格里的000412341234会变成412341234 7-14 会变成 2018-7-14(7月14) 自定义格式 web利用table表格生成excel格式问题 js导出excel增加表头、mso-number-format定义数据格式 数字输出格式转换 mso-number-format:"\@"

    Html Table用JS导出excel格式问题 我在网上找的JS把HTML Tabel导出成EXCEL.但是如果Table里的数字内容为0开的的导成Excel后会自动删除0,我想以text的格式写入 ...

  9. 【ASP.NET】C# 将HTML中Table导出到Excel(TableToExcel)

    首先,说下应用场景 就是,把页面呈现的Table 导出到Excel中.其中使用的原理是 前台使用ajax调用aspx后台,传递过去参数值,导出.使用的组件是NPOI. 前台调用: <script ...

随机推荐

  1. memcached内存模型

    内存管理 内存结构 把内存划分成不同的slab class仓库 把仓库切分成不同尺寸的小块(chunk),用来存储缓存数据 数据内存分配 首先根据数据的大小找到对应的slab class 找到空闲的c ...

  2. SQL Server中字段类型对应的C#中的数据类型

      数据库  C#程序  int                int32  text string bigint int64 binary System.Byte[] bit Boolean cha ...

  3. web前端学习(2):开始编写HTML

    在第一章中,我们初步了解了上网的过程,同时也明白了所谓网页,其本质就是主要用HTML语言所写的一份文档.相信大多数人在了解HTML文件前,最先接触的是利用"记事本"所写的文档或者是 ...

  4. Linux - ubuntu读取/root/.profile时发现错误:mesg:ttyname fa

    启动ubuntu,以root用户登陆,打开命令行终端 输入命令:#vim /root/.profile 找到.profile文件中的mesg n 将其替换成tty -s && mesg ...

  5. Effective Java 第三版——28. 列表优于数组

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  6. strman--java8字符串工具类

    strman-java 是Java8的字符串处理库,它的灵感来自 dleitee/strman . Strmen-java 是一个字符串处理工具,你可以通过 maven 将它引入到项目中.除了 Jav ...

  7. linux_操作系统

    如何查询操作系统版本? cat /etc/redhat-release 什么是操作系统? -- win10,linux都是os,应用软件和硬件打交道中间桥梁软件,管理 硬件+软件 资源,计算机系统基础 ...

  8. python_19_异常处理

    什么是异常处理? -- 对于用户输入,不想让用户看见出错信息,对异常进行处理 异常处理的框架是什么? try: 可能出错的程序1 可能出错的程序2        #程序1出错了,不在执行程序2 exc ...

  9. Log4j源码解析--核心类解析

    原文出处:http://www.blogjava.net/DLevin/archive/2012/06/28/381667.html.感谢上善若水的无私分享. 在简单的介绍了Log4J各个模块类的作用 ...

  10. PHP date()函数详解

    date (PHP 4, PHP 5) date - 格式化一个本地时间/日期 说明¶ string date ( string $format [, int $timestamp ] ) 返回将整数 ...