java解析页面table表格内容导出为excel

最近,因为项目中需要做到各个终端兼容,所以在报表预览时必须通用,所以采用后台生成html表格代码,前台通过jquery的load方法载入设置到指定位置。

生成excel时,通过解析html表格操作,就不要再去查询数据库组装den等操作了。

import java.io.ByteArrayInputStream;  
import java.io.File;  
import java.io.FileNotFoundException;  
import java.io.FileOutputStream;  
import java.io.IOException;  
import java.util.List;  
  
import org.apache.poi.hssf.usermodel.HSSFCell;  
import org.apache.poi.hssf.usermodel.HSSFRow;  
import org.apache.poi.hssf.usermodel.HSSFSheet;  
import org.apache.poi.hssf.usermodel.HSSFWorkbook;  
import org.apache.poi.hssf.util.CellRangeAddress;  
import org.apache.poi.ss.usermodel.CellStyle;  
import org.apache.poi.ss.usermodel.Font;  
import org.apache.poi.ss.usermodel.IndexedColors;  
import org.apache.poi.ss.usermodel.Workbook;  
import org.jdom.Element;  
import org.jdom.JDOMException;  
import org.jdom.input.SAXBuilder;  
  
/**根据table的html代码生成excel 
 * @param args 
 * zyn 
 * 2012-12-19 上午11:35:30 
 */  
public class TableToExcelUtil {  
  
      
    /** 
     *   
     * @param sheetName 
     * @param html 
     * @param headNum表头的行数 
     * @throws FileNotFoundException 
     * zyn 
     * 2012-12-21 下午1:44:02 
     */  
    public void createExcelFormTable(String sheetName,String html,int headNum) throws FileNotFoundException{  
        HSSFWorkbook wb = new HSSFWorkbook();  
        HSSFSheet sheet = wb.createSheet(sheetName);  
        CellStyle headStyle = this.createHeadStyle(wb);  
        CellStyle bodyStyle = this.createBodyStyle(wb);  
        FileOutputStream os = new FileOutputStream("c:\\table.xls");  
        SAXBuilder sb = new SAXBuilder();  
        ByteArrayInputStream is = new ByteArrayInputStream(html.getBytes());  
        try {  
            org.jdom.Document document = sb.build(is);  
            //获取table节点  
            Element root = document.getRootElement();  
            //获取tr的list  
            List<Element> trList = root.getChildren("tr");  
            int[][] area = getCellArea(trList);  
            //循环创建行  
            for(int i=0;i<trList.size();i++){  
                HSSFRow row = sheet.createRow(i);  
                List<Element> tdList = trList.get(i).getChildren("td");  
                //该行td的序号  
                int tdIndex = 0;  
                for(int ii=0;ii<area[i].length;ii++){  
                    row.createCell(ii);  
                    HSSFCell cell = row.getCell(ii);  
                    //判断是否为表头,使用对应的excel格式  
                    if(i<headNum){  
                        cell.setCellStyle(headStyle);  
                    }else{  
                        cell.setCellStyle(bodyStyle);  
                    }  
                    //如果对应的矩阵数字为1,则和横向前一单元格合并  
                    if(area[i][ii]==1){  
                        sheet.addMergedRegion(new CellRangeAddress(i,i,ii-1,ii));  
                    }else if(area[i][ii]==2){//如果对应的矩阵数字为2,则和纵向的前一单元格合并  
                        sheet.addMergedRegion(new CellRangeAddress(i-1,i,ii,ii));  
                    }else{//如果为0,显示td中对应的文字,td序号加1  
                        cell.setCellValue(this.getInnerText(tdList.get(tdIndex)));  
                        tdIndex ++;  
                    }  
                      
                }  
                  
            }  
                  
        wb.write(os);  
        } catch (JDOMException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  
      
    /** 
     * 导出excel表格二维数组:0为文字占用格,1为横向被合并格,2为纵向合并格 
     * @param trList 
     * @return 
     * zyn 
     * 2012-12-21 下午1:35:40 
     */  
      private static int[][] getCellArea(List<Element> trList){  
            //获取table单元格矩阵  
            Element headtr = trList.get(0);  
            List<Element> headTdList = headtr.getChildren("td");  
            //每行的未经合并的单元格个数  
            int cols = 0;  
            for(Element e:headTdList){  
                System.out.println("#"+e.getText());  
                int colspan = Integer.valueOf(null==e.getAttributeValue("colspan")?"0":e.getAttributeValue("colspan"));  
                if(colspan==0){  
                    colspan =1;  
                }  
                cols += colspan;  
            }  
            //初始化单元格矩阵  
            int[][] area = new int[trList.size()][cols];  
            for(int i=0;i<trList.size();i++){  
                Element tr = trList.get(i);  
                List<Element> tdList = tr.getChildren("td");  
          
                for(int ii=0,tdIndex=0;ii<cols;ii++){  
                    //如果大于0,表明已经处理过,不需再处理  
                    if(area[i][ii]>0){  
                        continue;  
                    }  
                    Element td = tdList.get(tdIndex);  
                    int colspan = Integer.valueOf(null==td.getAttributeValue("colspan")?"0":td.getAttributeValue("colspan"));  
                    colspan = colspan>1?colspan:1;  
                    //单元格需要被横向合并声明为1  
                    for(int m=1;m<colspan;m++){  
                        area[i][ii+m]=1;  
                    }  
                    int rowspan = Integer.valueOf(null==td.getAttributeValue("rowspan")?"0":td.getAttributeValue("rowspan"));  
                    rowspan = rowspan>1?rowspan:1;  
                    //单元格需要被纵向向合并声明为2  
                    for(int m=1;m<rowspan;m++){  
                        area[m+i][ii] = 2;  
                    }  
                    //列和行都有跨度的区域,把第一行,第一列外的区域置为2  
                    if(colspan>1 && rowspan>1){  
                        for(int j=1;j<rowspan;j++){  
                            for(int k=1;k<colspan;k++){  
                                area[i+j][ii+k]=2;  
                            }  
                        }  
                    }  
                    tdIndex ++;  
                }  
            }  
            return area;  
        }  
      
    /**- 
     * 设置表头样式 
     * @param wb 
     * @return 
     */  
    private CellStyle createHeadStyle(Workbook wb){  
        CellStyle style = wb.createCellStyle();  
        Font headerFont = wb.createFont();  
        headerFont.setBoldweight(Font.BOLDWEIGHT_BOLD);  
        style.setAlignment(CellStyle.ALIGN_CENTER);  
        style.setFillForegroundColor(IndexedColors.LIGHT_CORNFLOWER_BLUE.getIndex());  
        style.setFillPattern(CellStyle.SOLID_FOREGROUND);  
        style.setFont(headerFont);  
  
        style.setBorderRight(CellStyle.BORDER_THIN);  
        style.setRightBorderColor(IndexedColors.BLACK.getIndex());  
        style.setBorderBottom(CellStyle.BORDER_THIN);  
        style.setBottomBorderColor(IndexedColors.BLACK.getIndex());  
        style.setBorderLeft(CellStyle.BORDER_THIN);  
        style.setLeftBorderColor(IndexedColors.BLACK.getIndex());  
        style.setBorderTop(CellStyle.BORDER_THIN);  
        style.setTopBorderColor(IndexedColors.BLACK.getIndex());  
        return style;  
    }  
      
    /**- 
     * 设置表单记录样式 
     * @param wb 
     * @return 
     */  
    private CellStyle createBodyStyle(Workbook wb){  
        CellStyle style = wb.createCellStyle();  
        Font headerFont = wb.createFont();  
        headerFont.setBoldweight(Font.BOLDWEIGHT_NORMAL);  
        style.setAlignment(CellStyle.ALIGN_CENTER);  
        style.setFillForegroundColor(IndexedColors.LIGHT_GREEN.getIndex());  
        style.setFillPattern(CellStyle.SOLID_FOREGROUND);  
        style.setFont(headerFont);  
  
        style.setBorderRight(CellStyle.BORDER_THIN);  
        style.setRightBorderColor(IndexedColors.BLACK.getIndex());  
        style.setBorderBottom(CellStyle.BORDER_THIN);  
        style.setBottomBorderColor(IndexedColors.BLACK.getIndex());  
        style.setBorderLeft(CellStyle.BORDER_THIN);  
        style.setLeftBorderColor(IndexedColors.BLACK.getIndex());  
        style.setBorderTop(CellStyle.BORDER_THIN);  
        style.setTopBorderColor(IndexedColors.BLACK.getIndex());  
        return style;  
    }  
      
    private String getInnerText(Element td){  
        String txt = "";  
          if(td.getText()==null || td.getText().equals("")){  
           if(null != td.getChildren()){  
            for(int i=0;i<td.getChildren().size();i++){  
                Element e = (Element)td.getChildren().get(i);  
                 txt += getInnerText(e);  
            }  
         }  
          }else{  
     txt = td.getText();  
      }  
      return txt; }  
      
      
    public static void main(String[] args) throws FileNotFoundException {  
        // TODO Auto-generated method stub  
        TableToExcelUtil tu = new TableToExcelUtil();  
    //  System.out.println(tu.getInnerHtml(\"<td><a>1</a></td>\"));  
        tu.createExcelFormTable("缴费统计", "<table><tr class=\"titlebg\"><td align=\"center\" nowrap=\"nowrap\" rowspan=\"2\" colspan=\"1\">序号</td><td align=\"center\" nowrap=\"nowrap\" rowspan=\"2\" colspan=\"1\">计划</td><td align=\"center\" nowrap=\"nowrap\" rowspan=\"2\" colspan=\"1\">部门名称</td><td align=\"center\" nowrap=\"nowrap\" colspan=\"6\">线上缴费</td><td align=\"center\" nowrap=\"nowrap\" colspan=\"3\">线下缴费</td><td align=\"center\" nowrap=\"nowrap\" rowspan=\"2\" colspan=\"1\">总计</td></tr><tr class=\"titlebg\"><td align=\"center\" nowrap=\"nowrap\">线上总计</td><td align=\"center\" nowrap=\"nowrap\">快钱</td><td align=\"center\" nowrap=\"nowrap\">支付宝</td><td align=\"center\" nowrap=\"nowrap\">平台余款</td><td align=\"center\" nowrap=\"nowrap\">激活卡</td><td align=\"center\" nowrap=\"nowrap\">其他</td><td align=\"center\" nowrap=\"nowrap\">线下总计</td><td align=\"center\" nowrap=\"nowrap\">本地缴费</td><td align=\"center\" nowrap=\"nowrap\">中心收费</td></tr><tr class=\"whbg\" orgPath=\"01.25.01.\" planId=\"9e508516-5409-4b5d-a0d6-f86ba77eb79f\" ><td align=\"center\" nowrap=\"nowrap\">1</td><td align=\"center\" nowrap=\"nowrap\">盐城2013年培训计划</td><td align=\"center\" nowrap=\"nowrap\">盐城市</td><td align=\"center\" nowrap=\"nowrap\">0</td><td align=\"center\" nowrap=\"nowrap\">0</td><td align=\"center\" nowrap=\"nowrap\">0</td><td align=\"center\" nowrap=\"nowrap\">0</td><td align=\"center\" nowrap=\"nowrap\">0</td><td align=\"center\" nowrap=\"nowrap\">0</td><td align=\"center\" nowrap=\"nowrap\"><a id=\"0-12\" href=\"javascript:showDetail('0-12');\">3</a></td><td align=\"center\" nowrap=\"nowrap\">0</td><td align=\"center\" nowrap=\"nowrap\">0</td><td align=\"center\" nowrap=\"nowrap\"><a id=\"0-15\" href=\"javascript:showDetail('0-15');\">3</a></td></tr><tr class=\"whbg\" orgPath=\"all\" planId=\"all\"><td align=\"center\"  nowrap=\"nowrap\" colspan=\"3\" >总计</td><td align=\"center\" nowrap=\"nowrap\" >0</td><td align=\"center\" nowrap=\"nowrap\" >0</td><td align=\"center\" nowrap=\"nowrap\" >0</td><td align=\"center\" nowrap=\"nowrap\" >0</td><td align=\"center\" nowrap=\"nowrap\" >0</td><td align=\"center\" nowrap=\"nowrap\" >0</td><td align=\"center\" nowrap=\"nowrap\" ><a id=\"4-6\" href=\"javascript:showDetail('4-6');\">3</a></td><td align=\"center\" nowrap=\"nowrap\" >0</td><td align=\"center\" nowrap=\"nowrap\" >0</td><td align=\"center\" nowrap=\"nowrap\" ><a id=\"4-9\" href=\"javascript:showDetail('4-9');\">3</a></td></tr></table>", 2);  
    }  
  
}  










 用jdom解析table的html结构,用poi生成excel,html效果如下:

 

非常感谢小楼一夜听春雨 

解决了我的问题

原博文 :http://zyn010101.iteye.com/blog/1751678

 

posted @ 2015-07-09 15:47  JasonK  阅读(2746)  评论(0)    收藏  举报