Your file appears not to be a valid OLE2 document 报错解决

  1. 问题描述

在开发excel导入数据的过程中,客户想直接将导出的excel直接导入到另一个系统,但是在导入的过程中发现报上面的错误,百度一波解决方案都是另存为excel再导入,但是客户只接受直接导出然后导入,最后经过一系列探索发现,虽然导出的文件是xls后缀的,但是当你另存为的时候发现其实本质是html文件,最后就需要研究怎么从html转excel了

  1. 解决方法

先读取html内容为字符串,主要方法如下

 private String MultipartFileToString(MultipartFile multipartFile) {
        InputStreamReader isr;
        BufferedReader br;
        StringBuilder txtResult = new StringBuilder();
        try {
            isr = new InputStreamReader(multipartFile.getInputStream(), StandardCharsets.UTF_8);
            br = new BufferedReader(isr);
            String lineTxt;
            while ((lineTxt = br.readLine()) != null) {
                txtResult.append(lineTxt);
            }
            isr.close();
            br.close();
            return txtResult.toString();
        } catch (Exception e) {
           logger.error("文件读取失败");
            return "";
        }
    }

再讲字符串转为HSSFWorkbook,方法如下(从网络copy修改的)

package com.qingyuan.business.utils;

import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFPalette;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.IOException;
import java.util.*;

public class HtmlToExcel {
    /**
     * @param html      字符串的html
     * @param sheetName sheet页的名字
     * @throws IOException
     */
    public static HSSFWorkbook toExcel(String html, String sheetName) throws IOException {
        HSSFWorkbook wb = new HSSFWorkbook();

        //表头单元格风格
        HSSFCellStyle thStyle = wb.createCellStyle();
        thStyle.setFillForegroundColor(IndexedColors.AQUA.getIndex());
        thStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        //上下左右居中
        thStyle.setAlignment(HorizontalAlignment.CENTER);
        thStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        //边框
        thStyle.setBorderTop(BorderStyle.THIN);
        thStyle.setBorderRight(BorderStyle.THIN);
        thStyle.setBorderBottom(BorderStyle.THIN);
        thStyle.setBorderLeft(BorderStyle.THIN);
        thStyle.setTopBorderColor(IndexedColors.WHITE.getIndex());
        thStyle.setRightBorderColor(IndexedColors.WHITE.getIndex());
        thStyle.setBottomBorderColor(IndexedColors.WHITE.getIndex());
        thStyle.setLeftBorderColor(IndexedColors.WHITE.getIndex());
        //字体
        Font thFont = wb.createFont();
        thFont.setColor(IndexedColors.BLACK.getIndex());
        thFont.setBold(true);
        thStyle.setFont(thFont);
        Sheet sheet = wb.createSheet(sheetName);

        //获取html的数据
        List<List<Map<String, String>>> excelData = getExcelData(html);
        //处理数据
        for (int rowNum = 0; rowNum < excelData.size(); rowNum++) {
            //外层是循环行,每循环一次,创建一个行的对象
            Row row = sheet.createRow(rowNum);
            //设置行的高度
            row.setHeightInPoints(25);
            for (int cellNum = 0; cellNum < excelData.get(rowNum).size(); cellNum++) {

                //处理跨行跨列
                if ((excelData.get(rowNum).get(cellNum).get("colspanValue") != null) && (excelData.get(rowNum).get(cellNum).get("rowspanValue") != null)) {
                    int colspanValue = Integer.parseInt(excelData.get(rowNum).get(cellNum).get("colspanValue"));
                    int rowspanValue = Integer.parseInt(excelData.get(rowNum).get(cellNum).get("rowspanValue"));
                    sheet.addMergedRegion(new CellRangeAddress(rowNum, rowspanValue + rowNum - 1, cellNum, cellNum + colspanValue - 1));
                } else {
                    if (excelData.get(rowNum).get(cellNum).get("colspanValue") != null) {
                        int colspanValue = Integer.parseInt(excelData.get(rowNum).get(cellNum).get("colspanValue"));
                        sheet.addMergedRegion(new CellRangeAddress(rowNum, rowNum, cellNum, cellNum + colspanValue - 1));
                    }
                    if (excelData.get(rowNum).get(cellNum).get("rowspanValue") != null) {
                        int rowspanValue = Integer.parseInt(excelData.get(rowNum).get(cellNum).get("rowspanValue"));
                        sheet.addMergedRegion(new CellRangeAddress(rowNum, rowspanValue + rowNum - 1, cellNum, cellNum));
                    }
                }

                //内层循环每行的单元格,每循环一次,创建一个单元格的对象
                Cell cell = row.createCell(cellNum);
                //赋值
                cell.setCellValue(excelData.get(rowNum).get(cellNum).get("value"));

                //设置样式
                if (excelData.get(rowNum).get(cellNum).get("style") != null) {
                    if ("th".equals(excelData.get(rowNum).get(cellNum).get("style"))) {
                        cell.setCellStyle(thStyle);
                    }
                    if ("td".equals(excelData.get(rowNum).get(cellNum).get("style"))) {

                        //表体
                        HSSFCellStyle tdStyle = wb.createCellStyle();
                        tdStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
                        //上下左右居中
                        tdStyle.setAlignment(HorizontalAlignment.CENTER);
                        tdStyle.setVerticalAlignment(VerticalAlignment.CENTER);
                        //边框
                        tdStyle.setBorderTop(BorderStyle.THIN);
                        tdStyle.setBorderRight(BorderStyle.THIN);
                        tdStyle.setBorderBottom(BorderStyle.THIN);
                        tdStyle.setBorderLeft(BorderStyle.THIN);
                        tdStyle.setTopBorderColor(IndexedColors.WHITE.getIndex());
                        tdStyle.setRightBorderColor(IndexedColors.WHITE.getIndex());
                        tdStyle.setBottomBorderColor(IndexedColors.WHITE.getIndex());
                        tdStyle.setLeftBorderColor(IndexedColors.WHITE.getIndex());

                        if (rowNum % 2 == 0) {
                            tdStyle.setFillForegroundColor(IndexedColors.LIGHT_TURQUOISE.getIndex());
                        } else {
                            tdStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
                        }
                        cell.setCellStyle(tdStyle);
                    }
                }

                //设置宽度
                sheet.setColumnWidth(cellNum, (excelData.get(rowNum).get(cellNum).get("value").length() + 20) * 256);
            }
        }

        HSSFPalette palette = wb.getCustomPalette();

        //获取配置的颜色
        palette.setColorAtIndex(IndexedColors.ORANGE.getIndex(),
                (byte) 97, //RGB red (0-255)
                (byte) 191, //RGB green
                (byte) 130 //RGB blue
        );
        palette.setColorAtIndex(IndexedColors.BLUE.getIndex(),
                (byte) 233, //RGB red (0-255)
                (byte) 244, //RGB green
                (byte) 232 //RGB blue
        );
        return wb;
    }

    public static List<List<Map<String, String>>> getExcelData(String tableHtml) {
        Document document = Jsoup.parse(tableHtml);

        //取得表体的html
        Elements tbody = document.select("tbody").select("tr");

        //获取table的最大的列数
        List<Integer> tdSize = new ArrayList<>();
        for (Element element : tbody) {
            tdSize.add(element.select("td").size());
        }
        Collections.sort(tdSize);

        //最后一行就是整个表格最大的列数
        int rowCellNum = tdSize.get(tdSize.size() - 1);

        //整个table的<tr>
        Elements trAll = document.select("tr");
        //tr就是整个表格的行数
        int excelDataSize = trAll.size();

        //存放表格数据
        List<List<Map<String, String>>> excelData = new ArrayList<>();
        //先创建空的excel数据
        for (int i = 0; i < excelDataSize; i++) {
            excelData.add(new ArrayList<>());
            for (int j = 0; j < rowCellNum; j++) {
                excelData.get(i).add(new HashMap<>());
            }
        }

        //按行数进行循环
        for (int rowNum = 0; rowNum < excelData.size(); rowNum++) {
            //取得每一行的html
            Element element = trAll.get(rowNum);

            //这一行的表头
            Elements th = element.select("th");
            Elements td = element.select("td");

            //列数
            int index = 0;

            //循环一行的数据
            for (int cellNum = 0; cellNum < excelData.get(rowNum).size(); cellNum++) {

                //只有value==null的才是没有被赋值的,因为跨行跨列的已经赋值过了
                if (excelData.get(rowNum).get(cellNum).get("value") == null) {
                    //取一个单元格对象
                    Element cell = null;
                    //样式的标识
                    String style = "";

                    //表头th处理
                    if (th.size() != 0) {
                        //这是表头的样式
                        style = "th";
                        excelData.get(rowNum).get(cellNum).put("style", style);
                        if (th.size() > index) {
                            cell = th.get(index);
                        }
                    }

                    //表体td处理
                    if (td.size() != 0) {
                        //这是表体的样式
                        style = "td";
                        excelData.get(rowNum).get(cellNum).put("style", style);
                        if (td.size() > index) {
                            cell = td.get(index);
                        }
                    }
                    //单元格的值
                    String value = cell == null ? "" : cell.text();

                    //处理跨行跨列
                    String cellHtml = cell == null ? "" : cell.outerHtml();
                    //rowspan和colspan都有值的情况下
                    if ((cellHtml.indexOf("rowspan") != -1 && cellHtml.indexOf("\"\"") == -1) || (cellHtml.indexOf("colspan") != -1 && cellHtml.indexOf("\"\"") == -1)) {
                        String rowspanValue = "0";
                        String colspanValue = "0";

                        //rowspan有值 取值并给到单元格对象
                        if (cellHtml.indexOf("rowspan") != -1 && cellHtml.indexOf("\"\"") == -1) {
                            String rowspanValueStr = cellHtml.substring(cellHtml.indexOf("rowspan") + 7);
                            rowspanValueStr = rowspanValueStr.substring(rowspanValueStr.indexOf("\"") + 1);
                            rowspanValueStr = rowspanValueStr.substring(0, rowspanValueStr.indexOf("\""));
                            rowspanValue = rowspanValueStr;
                            excelData.get(rowNum).get(cellNum).put("rowspanValue", rowspanValue);
                        }
                        //colspan有值 取值并给到单元格对象
                        if (cellHtml.indexOf("colspan") != -1 && cellHtml.indexOf("\"\"") == -1) {
                            String colspanValueStr = cellHtml.substring(cellHtml.indexOf("colspan") + 7);
                            colspanValueStr = colspanValueStr.substring(colspanValueStr.indexOf("\"") + 1);
                            colspanValueStr = colspanValueStr.substring(0, colspanValueStr.indexOf("\""));
                            colspanValue = colspanValueStr;
                            excelData.get(rowNum).get(cellNum).put("colspanValue", colspanValue);
                        }

                        //这个单元格又跨行又跨列
                        if (Integer.parseInt(rowspanValue) > 0 && Integer.parseInt(colspanValue) > 0) {

                            //把他跨列的单元格给赋上值 , 没有赋值就是null  ,  和559行的逻辑呼应
                            for (int i = 1; i < Integer.parseInt(rowspanValue); i++) {
                                excelData.get(rowNum + i).get(cellNum).put("value", value);
                                excelData.get(rowNum + i).get(cellNum).put("style", style);

                                //把他跨行的单元格给赋上值 , 没有赋值就是null  ,  和559行的逻辑呼应
                                for (int j = 1; j < Integer.parseInt(colspanValue); j++) {
                                    excelData.get(rowNum).get(cellNum + j).put("value", value);
                                    excelData.get(rowNum).get(cellNum + j).put("style", style);
                                    excelData.get(rowNum + i).get(cellNum + j).put("value", value);
                                    excelData.get(rowNum + i).get(cellNum + j).put("style", style);
                                }
                            }
                        }
                        //跨行或者跨列
                        else {
                            //跨列
                            if (Integer.parseInt(rowspanValue) > 0) {
                                //把他跨列的单元格给赋上值 , 没有赋值就是null  ,  和559行的逻辑呼应
                                for (int i = 1; i < Integer.parseInt(rowspanValue); i++) {
                                    excelData.get(rowNum + i).get(cellNum).put("value", value);
                                    excelData.get(rowNum + i).get(cellNum).put("style", style);
                                }
                            }
                            if (Integer.parseInt(colspanValue) > 0) {
                                //把他跨行的单元格给赋上值 , 没有赋值就是null  ,  和559行的逻辑呼应
                                for (int j = 1; j < Integer.parseInt(colspanValue); j++) {
                                    excelData.get(rowNum).get(cellNum + j).put("value", value);
                                    excelData.get(rowNum).get(cellNum + j).put("style", style);
                                }
                            }
                        }
                    }
                    excelData.get(rowNum).get(cellNum).put("value", value);
                    index = index + 1;
                }
            }
        }
        return excelData;
    }
}

然后就是内容读取了

注:在这当中遇到的坑

  1. html转excel之后,数据所在行和原来的文件对不上,需要自己去看转换的内容,表头,数据在哪一行。像下面这种表格,解析之后会自动去掉第一行,测试合并的行算一行

  1. 转换之后,原来表格的数字会全部转变为字符串,并且像下图这种数据带有,的,需要自己去替换掉,并且转换成数字,不然会报错

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这个错误提示意味着你的文件似乎不是有效的OLE2文档。OLE2是一种文件格式,通常用于Microsoft Office文档,如.doc、.xls和.ppt文件。如果你尝试打开一个不是OLE2格式的文件,可能会收到这个错误消息。 如果你确信文件应该是一个OLE2文档,那么可能是文件已经损坏或损坏了部分数据。你可以尝试打开备份文件(如果有的话)或从其他来源获取原始文件。如果这仍然无法解决问题,你可能需要使用专业的文件恢复工具来尝试恢复文件。 ### 回答2: 你的文件似乎不是一个有效的OLE2文档,这可能是由于以下几个原因导致的: 1.文件损坏:这意味着文件在传输或存储期间出现问题,可能导致数据丢失或文件完全无法读取。尝试使用备份文件或重新下载原始文件。 2.文件格式错误:如果文件不是正确的OLE2文件格式,可能会导致此错误。确保文件扩展名与其所属的应用程序兼容。 3.应用程序不兼容:某些应用程序可能无法打开特定类型的OLE2文件。确保您使用的应用程序与文件兼容,或查找可以打开该文件类型的其他应用程序。 4.文件权限问题:如果您对文件没有足够的权限,则无法打开该文件。尝试将文件移动到不同的文件夹或更改其权限以授予您对文件的完全访问权限。 如果您正在尝试打开Microsoft Office文档,则可能需要尝试以下方法: 1.使用修复文件功能:如果您的Office应用程序提供了修复文件功能,则可以尝试使用该功能来修复文件。 2.使用其他Office应用程序打开:有时,您可以将损坏的文档导入到另一个Office应用程序(如Word)中,然后再将其导出为新的文件。 3.使用第三方工具:可以尝试使用第三方工具来修复文件。这些工具可能不适用于所有类型的文档,但可能是一种解决问题的方法。 总之,如果您遇到"your file appears not to be a valid ole2 document"的错误提示,首先请确保文件未损坏,并使用与文件兼容的应用程序打开该文件。如果仍然无法打开,请尝试使用上述方法进行修复。 ### 回答3: “your file appears not to be a valid ole2 document”这个错误通常出现在Office文件中。这可能意味着这个文件已经损坏或者格式不正确。其中可能存在一些原因: 首先,这个错误信息表明这个文件不是一个有效的OLE2文档。OLE2是插入对象的通用规范,用于在多个应用程序间共享数据和代码。如果文件损坏或者格式不正确,OLE2无法识别它。 其次,这个错误信息可能意味着您正在尝试打开错误的文件格式。例如,您正在尝试打开不受支持的Office版本或者其他Microsoft Office之外的软件打开的文件。 还有一些其他的可能原因。可能是您的电脑没有足够的内存或者硬盘空间来读取文件。也可能是因为文件的路径名称过长。 解决这个问题有多种方法,以下是一些可能有用的建议: 首先,您可以尝试从备份中恢复文件。如果您有一个备份,可以尝试从备份中恢复文件。这通常是最安全和最有效的方法。 其次,您可以尝试卸载和重新安装Microsoft Office。 如果可能的话,首先备份您的重要文件。重新安装Office可能会修复系统文件和损坏的Office文件。 最后,您可以尝试使用其他软件打开文件。如果所有的方法都失败了,您可以尝试使用其他软件打开文件。有些软件能够识别并打开受损的Office文件,并尝试恢复尽可能多的数据。 总之,当看到“your file appears not to be a valid ole2 document”这个错误提示时,不要惊慌。尝试使用上述建议来解决问题,如果仍然无法解决,请咨询专业人员获取更多帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值