Java如何提取格式/扩展名不匹配的XLS文件文本?
问题分析
你遇到的错误是因为文件后缀与实际格式不匹配:你命名为Export.xls的文件并非标准的Excel 97-2003(OLE2格式)文件,从错误日志里的头签名0x6D78206C6D74683C可推断,它实际是HTML格式(转成ASCII是<html xm),只是被改成了.xls后缀。Excel能打开是因为它会自动检测文件真实格式,而你原代码里的HSSFWorkbook仅支持标准OLE2格式的XLS文件,因此抛出无效头签名错误。
解决方案
通过自动识别文件真实格式,选择对应的解析方式即可解决问题。以下提供两种可行实现:
方案1:使用POI自动工厂类+HTML解析 fallback
先尝试用POI的WorkbookFactory处理标准XLS/XLSX文件,失败则用jsoup解析HTML格式的表格内容:
依赖准备(Maven)
<dependencies> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>5.2.5</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>5.2.5</version> </dependency> <dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.17.2</version> </dependency> </dependencies>
代码实现
import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.WorkbookFactory; import org.apache.poi.ss.extractor.ExcelExtractor; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; import java.io.File; import java.io.FileInputStream; import java.io.IOException; public class ExcelTextExtractor { public static void main(String[] args) { File expFile = new File("Export.xls"); String expFileText = ""; // 尝试用POI处理标准Excel格式 try (FileInputStream fis = new FileInputStream(expFile)) { Workbook workbook = WorkbookFactory.create(fis); ExcelExtractor extractor = ExcelExtractor.createExtractor(workbook); expFileText = extractor.getText(); } catch (Exception e) { // 失败则尝试解析HTML表格 try { Document doc = Jsoup.parse(expFile, "UTF-8"); StringBuilder sb = new StringBuilder(); Elements tables = doc.select("table"); for (Element table : tables) { Elements rows = table.select("tr"); for (Element row : rows) { Elements cells = row.select("td, th"); for (Element cell : cells) { sb.append(cell.text()).append("\t"); } sb.append("\n"); } } expFileText = sb.toString(); } catch (IOException ioException) { ioException.printStackTrace(); } } System.out.println("Export xls file text: " + expFileText); } }
方案2:先检测文件头,精准匹配解析方式
读取文件前8字节判断真实格式,再选择对应解析逻辑,避免try-catch的开销:
代码实现
import org.apache.poi.hssf.extractor.ExcelExtractor; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; import java.io.File; import java.io.FileInputStream; import java.io.IOException; public class ExcelTextExtractor { public static void main(String[] args) { File expFile = new File("Export.xls"); String expFileText = ""; try { String fileHeader = getFileHeader(expFile); try (FileInputStream fis = new FileInputStream(expFile)) { if (fileHeader.startsWith("D0CF11E0A1B11AE1")) { // 标准Excel 97-2003格式 HSSFWorkbook hwb = new HSSFWorkbook(fis); ExcelExtractor extractor = new ExcelExtractor(hwb); expFileText = extractor.getText(); } else if (fileHeader.startsWith("504B0304")) { // XLSX格式(后缀被修改为xls) XSSFWorkbook xwb = new XSSFWorkbook(fis); ExcelExtractor extractor = new ExcelExtractor(xwb); expFileText = extractor.getText(); } else if (fileHeader.startsWith("3C68746D6C")) { // HTML格式(后缀被修改为xls) Document doc = Jsoup.parse(expFile, "UTF-8"); StringBuilder sb = new StringBuilder(); Elements tables = doc.select("table"); for (Element table : tables) { Elements rows = table.select("tr"); for (Element row : rows) { Elements cells = row.select("td, th"); for (Element cell : cells) { sb.append(cell.text()).append("\t"); } sb.append("\n"); } } expFileText = sb.toString(); } else { throw new IOException("不支持的文件格式"); } } } catch (IOException e) { e.printStackTrace(); } System.out.println("Export xls file text: " + expFileText); } // 获取文件前8字节的十六进制头 private static String getFileHeader(File file) throws IOException { try (FileInputStream fis = new FileInputStream(file)) { byte[] header = new byte[8]; fis.read(header); StringBuilder sb = new StringBuilder(); for (byte b : header) { sb.append(String.format("%02X", b)); } return sb.toString(); } } }
关键说明
WorkbookFactory.create()会自动识别标准XLS/XLSX格式,无需手动指定HSSF或XSSF类。- HTML格式的文件通过jsoup解析表格,模拟Excel打开时的内容提取逻辑,保证内容一致性。
内容的提问来源于stack exchange,提问作者AutoTester999
相关产品推荐
相关产品推荐

