使用者上傳 Office 文件,網頁需像百度文庫、豆丁網一樣**線上預覽、翻頁、縮放、全螢幕**,不需下載。核心技術路線:
安裝虛擬印表機驅動 → 列印文件 → 截獲 EMF → 轉 SWF/PDF。
"C:\Program Files\Macromedia\FlashPaper 2\FlashPrinter.exe" "input.ppt" -o "output.swf"
exec('"C:\Program Files\Macromedia\FlashPaper 2\FlashPrinter.exe" "input.docx" -o "output.swf"', $out, $ret);
if ($ret !== 0) throw new Exception("FlashPaper 轉換失敗: " . implode("\n", $out));
使用者上傳 → PHP 儲存 → 佇列 → Worker 呼叫
1. LibreOffice (headless) --convert-to pdf → output.pdf
2. swftools pdf2swf -T 9 output.pdf -o output.swf
3. 回傳 SWF 路徑 / 狀態
前端 AS3/JS 載入 SWF 序列 → 翻頁預覽
# 1. 安裝 LibreOffice (無介面)
yum install -y libreoffice-headless fonts-chinese # CentOS
apt-get install -y libreoffice fonts-wqy-zenhei # Ubuntu
# 2. 安裝 swftools
yum install -y swftools # 或從源碼編譯 ./configure --prefix=/usr/local/swftools && make install
# 3. 啟動 LibreOffice Socket 服務 (常駐,避免每次冷啟動)
/opt/libreoffice/program/soffice -headless -accept="socket,host=127.0.0.1,port=8100;urp;" -nofirststartwizard &
# 4. PHP 呼叫 (使用 JODConverter 或直呼指令)
# 直呼指令範例:
exec('libreoffice --headless --convert-to pdf --outdir /tmp/upload/ /tmp/upload/input.docx 2>&1', $out, $ret);
exec('/usr/local/swftools/bin/pdf2swf -T 9 /tmp/upload/input.pdf -o /tmp/upload/input.swf 2>&1', $out, $ret);
LocalConverter converter = LocalConverter.builder()
.officeHome("/opt/libreoffice")
.portNumbers(8100)
.build();
converter.convert(new File("input.docx")).to(new File("output.pdf")).execute();
| 參數 | 說明 |
|---|---|
| `pdf2swf -T 9` | 輸出 **Flash Player 9** 相容 SWF (ActionScript 3),否則預設輸出 FP7/8,AS3 無法操作 |
| `-s poly2bitmap` | 複雜向量轉位圖,避免渲染錯誤 |
| `-s zoom=100` | 縮放比例 |
| 方案 | 技術 | 優點 | 缺點 |
|---|---|---|---|
| FlexPaper / FlowPaper | AS3 / JS | 成熟商業元件、支援註釋、搜尋、下載控制 | 需授權費、Flash 瀏覽器已淘汰 |
| PDF.js (Mozilla) | 純 JS + Canvas | **無需 Flash**、支援文字選取、搜尋、響應式、行動裝置完美 | 大檔案渲染較慢、複雜排版偶有誤差 |
| 自製 AS3 Player | AS3 | 完全控制 | 開發成本高、Flash 死路一條 |
2024+ 專案強烈建議:Office → PDF → PDF.js,徹底避開 Flash/SWF 技術債。
[上傳 API] → [MinIO/S3] → [轉換佇列] → [Worker: LibreOffice + pdf2swf/pdf2htmlEX] → [MinIO/S3] → [前端 PDF.js 載入]
│ │
└────────────── 狀態輪詢 / WebSocket 推送 ────────────────┘