首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Java 解析 MHT/MHTML 格式偽裝的 Excel 文件:自動化批量轉換方案

     編輯:程式設計綜合問答

問題本質

第三方平台輸出的 .xls 實為 MHTML (MIME HTML) 格式,內容為 Content-Transfer-Encoding: quoted-printable 編碼的 HTML 表格(如 =E4=B8=AD 代表「中」)。POI/JXL 無法直接解析。

方案一:Java 純代碼解析 MHTML → 轉真實 Excel(推薦,無外部依賴)

<dependency>
    <groupId>org.apache.james</groupId>
    <artifactId>apache-mime4j</artifactId>
    <version>0.8.7</version>
</dependency>

// 1. 解析 MIME 結構
MimeMessageParser parser = new MimeMessageParser(new MimeStreamParser().parse(new FileInputStream("fake.xls")));
parser.parse();

// 2. 取得 text/html 部分
String html = parser.getHtmlContent(); // 或遍歷 body parts 找 text/html

// 3. Quoted-Printable 解碼
String decoded = MimeUtility.decodeText(html.replace("=\r\n", "")); // 移除軟換行

// 4. 解析 HTML 表格 → POI 寫入真實 .xlsx
Document doc = Jsoup.parse(decoded);
Element table = doc.select("table").first();
Workbook wb = new XSSFWorkbook();
Sheet sh = wb.createSheet();
int r = 0;
for (Element row : table.select("tr")) {
    Row xr = sh.createRow(r++);
    int c = 0;
    for (Element cell : row.select("td,th")) {
        xr.createCell(c++).setCellValue(cell.text());
    }
}
try (FileOutputStream fos = new FileOutputStream("real.xlsx")) { wb.write(fos); }

方案二:LibreOffice 無頭模式批量轉換(最省力、兼容性最強)

// Linux/Mac/Windows 均可
libreoffice --headless --convert-to xlsx:"Calc MS Excel 2007 XML" --outdir /output /input/*.xls
  • 可直接處理 MHTML、HTML、CSV 等偽裝格式。
  • 支援超大批量、保留格式/公式、無需寫代碼。
  • 部署需安裝 LibreOffice,服務器環境需無圖形介面依賴(--headless 已解決)。

方案三:Python + pandas/openpyxl 腳本(輕量、易維護)

import quopri, re, pandas as pd
from bs4 import BeautifulSoup

def mhtml_to_xlsx(src, dst):
    with open(src, 'rb') as f: raw = f.read()
    # 簡易提取 HTML 部分(實際建議用 email.parser)
    html_part = re.search(b'Content-Type: text/html.*?\r\n\r\n(.*?)\r\n--', raw, re.DOTALL)
    if not html_part: return
    html = quopri.decodestring(html_part.group(1)).decode('utf-8', errors='ignore')
    tables = pd.read_html(html)
    if tables:
        tables[0].to_excel(dst, index=False)

# 批量
for f in glob.glob('input/*.xls'):
    mhtml_to_xlsx(f, f.replace('input', 'output').replace('.xls', '.xlsx'))

方案對比與選型

方案優點缺點適用場景
Java + mime4j + Jsoup + POI純 Java、嵌入服務、可定製清洗邏輯代碼量大、需處理 MIME 邊界情況Java 微服務、需在線轉換
LibreOffice headless零代碼、兼容性極強、保留樣式啟動慢、佔記憶體、需安裝辦公套件離線批量、定時任務、格式複雜
Python 腳本輕量、開發快、生態豐富需額外運行時、大文件效能一般運維腳本、一次性遷移、團隊懂 Python

關鍵提示

  • MHTML 內部常含多個 Part(text/plain、text/html、image/...),務必提取 text/html。
  • Quoted-Printable 解碼需移除軟換行 =\r\n 後再解碼。
  • HTML 表格可能巢狀、合併儲存格,pd.read_html 或 Jsoup 選第一個 <table> 通常足夠;複雜情況需自行遍歷 DOM。
  • 輸出建議用 .xlsx (OOXML),避免 .xls 65535 行限制。

根據團隊技術棧、部署環境、實時性要求選擇;LibreOffice 批量轉換通常性價比最高。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved