将excel表格转化为html文本

来源:互联网 发布:天猫 淘宝商城秒杀 编辑:程序博客网 时间:2024/05/08 09:30

场景:产生每日的报表并通过邮件发送时,PM提出需要将报表excel(附件)中的内容展现在正文中

当时一想法是某企鹅的邮箱就实现了这个功能,是否在poi接口或者在java email相关的类中有类似的方法,但是找了之后发现并没有可以调用的方法,所以就自己封装了一下,进行简单的数据提取。


/** * 将excel内容提取转化为html格式以便在邮件中使用 * @author JK Terrific * */public class Excel2HtmlUtil {    private static Map<Integer, Boolean> combineState = new HashMap<Integer, Boolean>();    /**    * 合并单元格处理--加入list    *    * @param sheet    * @return    */    private static void getCombineCell(HSSFSheet sheet, List<CellRangeAddress> list) {        // 获得一个 sheet 中合并单元格的数量        int sheetmergerCount = sheet.getNumMergedRegions();        // 遍历合并单元格        for (int i = 0; i < sheetmergerCount; i++) {            // 获得合并单元格加入list中            CellRangeAddress ca = sheet.getMergedRegion(i);            list.add(ca);            combineState.put(i, false);        }    }    /**    * 判断单元格是否为合并单元格    *    * @param listCombineCell    * 存放合并单元格的list    * @param cell    * 需要判断的单元格    * @param sheet    * sheet    * @return 合并单元格列表的索引 若不存在返回-1    */    private static Integer isCombineCell(List<CellRangeAddress> listCombineCell, HSSFCell cell,            HSSFSheet sheet) {        int firstC = 0;        int lastC = 0;        int firstR = 0;        int lastR = 0;        for (int i = 0; i < listCombineCell.size(); i++) {            CellRangeAddress ca = listCombineCell.get(i);            // 获得合并单元格的起始行, 结束行, 起始列, 结束列            firstC = ca.getFirstColumn();            lastC = ca.getLastColumn();            firstR = ca.getFirstRow();            lastR = ca.getLastRow();            if (cell.getColumnIndex() <= lastC && cell.getColumnIndex() >= firstC) {                if (cell.getRowIndex() <= lastR && cell.getRowIndex() >= firstR) {                    return i;                }            }        }        return -1;    }    private static String getCombineTableTag(CellRangeAddress rangeAddress) {        StringBuffer tableTag = new StringBuffer("");        int firstC = 0;        int lastC = 0;        int firstR = 0;        int lastR = 0;        firstC = rangeAddress.getFirstColumn();        lastC = rangeAddress.getLastColumn();        firstR = rangeAddress.getFirstRow();        lastR = rangeAddress.getLastRow();        tableTag.append("<td align=\"center\"");        if (firstC != lastC) {            tableTag.append(" colspan =\"");            tableTag.append(lastC - firstC + 1);            tableTag.append("\"");        }        if (firstR != lastR) {            tableTag.append(" rowspan =\"");            tableTag.append(lastR - firstR + 1);            tableTag.append("\"");        }        tableTag.append(">");        return tableTag.toString();    }    public static String getTableBody(HSSFSheet sheet) throws IOException, InterruptedException {        StringBuffer tableBody = new StringBuffer("");        tableBody.append("<table border=\"1\">");        List<CellRangeAddress> listCombineCell = new ArrayList<CellRangeAddress>();        //获得所有合并单元格,在下面用于判断单元格是否合并        getCombineCell(sheet, listCombineCell);        //遍历所有列        Iterator<Row> rowIterator = sheet.rowIterator();        while (rowIterator.hasNext()) {            tableBody.append("<tr>");            //遍历所有行            Row row = rowIterator.next();            Iterator<Cell> cellIterator = row.cellIterator();            //遍历所有的单元格            while (cellIterator.hasNext()) {                Cell cell = cellIterator.next();                //设置单元格格式为字符串方便后续取得                cell.setCellType(HSSFCell.CELL_TYPE_STRING);                //获取当前单元格属于哪个被合并的单元格                Integer combineIndex = isCombineCell(listCombineCell, (HSSFCell) cell, sheet);                //如果是被合并的单元格                if (combineIndex >= 0) {                    //查看是否已经在html中合并                    if (combineState.get(combineIndex)) {                        continue;                    } else {                        //若为合并则添加合并标签                        tableBody.append(getCombineTableTag(listCombineCell.get(combineIndex)));                        tableBody.append(cell.getStringCellValue());                        tableBody.append("</td>");                        combineState.put(combineIndex, true);                    }                } else {                    tableBody.append("<td align=\"center\">");                    tableBody.append(cell.getStringCellValue());                    tableBody.append("</td>");                }            }        }        tableBody.append("</table>");        return tableBody.toString();    }    private static String addToHtml(String bodyContent) throws IOException, InterruptedException {        StringBuffer html = new StringBuffer("");        html.append("<html>");        html.append("<head>");        html.append("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">");        html.append("<title>Insert title here</title>");        html.append("</head>");        html.append("<body>");        /**         * 在这里插入正文         */        html.append(bodyContent);        html.append("</body>");        html.append("</html>");        return html.toString();    }    public static String getHTMLContent(HSSFSheet sheet) throws IOException, InterruptedException {        String bodyContent = getTableBody(sheet);        return addToHtml(bodyContent);    }    public static String getHTMLContent(HSSFWorkbook workbook)            throws IOException, InterruptedException {        StringBuffer bodyContent = new StringBuffer("");        Iterator<Sheet> sheetItrator = workbook.sheetIterator();        while (sheetItrator.hasNext()) {            bodyContent.append(getTableBody((HSSFSheet) sheetItrator.next()));        }        return addToHtml(bodyContent.toString());    }}

思路使用迭代器进行数据的循环遍历(因为poi遍历只支持迭代器。。),然后将sheet中的所有合并单元格取出维护到一个list容器中,对每个单元格进行判断是否属于某个被合并的单元格。由于excel被合并的单元格只显示最左上方单元格的内容,所以从上到下从左到右遍历到一个新的,属于合并的单元格时,在新的td标签中添加colspan 和rowspan 值,并将

combineState 
的值设为true,表示已被放入html中,后续的单元格可以直接continue忽略。若遍历到的单元格不是第一个被合并的,则去判断combineState 的值是否为true。

最后得到完整的html代码。



1 0
原创粉丝点击