HTML XML TXT 格式的excel或其他类型的文件转换成正常xls文件

本人在一次工作中需要将下载的民生银行流水上传至服务器,但发现下载下来的民生银行excel流水文件不是正常的xls文件,导致poi-workbook不能成功读取,所以撰写此工具类进行格式转换,数据录入,特此记录

package com.nova2pay.pw.basic.util;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
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.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.apache.poi.ss.util.CellRangeAddress;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;  
  
/**根据table的html代码生成excel 
 * @param args 
 * LT 
 * 2020-12-19 上午15:10:30 
 */  
public class HtmlToXlsUtil {  
  
      
    /** 
     *   
     * @param sheetName sheet名称
     * @param html 从文本 xml  html 中读取到 数据(本例子中以html格式的excel文档为例,截取了table这部分(需要循环数据【tr】的上一级目录进行的)的数据,然后读取数据循环写入xls文件中 )
     * @param headNum表头的行数 
     * @throws FileNotFoundException 
     * LT 
     * 2020-12-21 15:20:02 
     */  
    public void createExcelFormTable(String sheetName,String html,int headNum,String filePath) 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(filePath);  
        SAXBuilder sb = new SAXBuilder();  
        try {  
            ByteArrayInputStream is = new ByteArrayInputStream(html.getBytes("UTF-8"));
            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();  
        }  
    }  
      
    /** 
     * 有的文件中  涉及到js格式等,占用多格等问题,这个并不重要,只要数据成功录入,根据新的文件读取数据即可
     * 这里仅仅是为了让新的excel中的内容格式尽量跟原版相似
     * 导出excel表格二维数组:0为文字占用格,1为横向被合并格,2为纵向合并格 
     * @param trList 
     * @return 
     * LT 
     * 2020-10-15 15: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;  
    }  
    /**
     * 从源文件的内容中中找到需要的数据(本文以table为例找的tr,td内容)
     * @param td
     * @return
     */
    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; }  
      
    
    /**
     * 读取文件中的内容并输入,以便后续读取数据写入新的文件
     * @param filePath
     * @return
     */
    public static String readHtml(File filePath) {
        BufferedReader br=null;
        StringBuffer sb = new  StringBuffer();
        try {
        br=new BufferedReader(new InputStreamReader(new FileInputStream(filePath),"UTF-8"));           
        String temp=null;       
        while((temp=br.readLine())!=null){
        sb.append(temp);
        }           
        } catch (FileNotFoundException e) {
        e.printStackTrace();
        } catch (IOException e) {
        e.printStackTrace();
        }
        return sb.toString();
        }
    
    
      
        public static void main(String[] args) throws FileNotFoundException {  
            HtmlToXlsUtil tu = new HtmlToXlsUtil();  
            //这里最后的replace  因为有的文件中特殊的css样式设计导致不能成功识别,所以去掉这些 样式
            String htmlstr = readHtml(new File("C:\\ABC\\download\\账号6226220219215836交易明细.xls")).replace("x:str", "");
            //仅仅截取table中的主体数据进行数据读取
            String str = htmlstr.substring(htmlstr.indexOf("<table"),htmlstr.indexOf("</table>")+8);
            System.out.println(str);
            tu.createExcelFormTable("民生银行流水统计", str, 4,"C:\\table.xls");  
        }  
    
        /* public static void main(String[] args) throws BiffException, IOException {
            File file = new File("C:\\table.xls");
            jxl.Workbook workbook = jxl.Workbook.getWorkbook(file);
            System.out.println(workbook.getNumberOfSheets());
            System.out.println(workbook.getSheet(0).getRows());
            System.out.println(workbook.getSheet(0).getRow(5));
            System.out.println(workbook.getSheet(0).getColumns());
            System.out.println(workbook.getSheet(0).getCell(5, 3).getContents());
        }*/
  
}

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页