|
|
@@ -1,5 +1,7 @@
|
|
|
/** 合同打印弹窗:HTML → DOCX 预处理与生成 */
|
|
|
|
|
|
+import { Buffer } from 'buffer'
|
|
|
+
|
|
|
const DOCX_MIME = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
|
|
|
|
|
|
type HtmlToDocxFn = (
|
|
|
@@ -9,13 +11,30 @@ type HtmlToDocxFn = (
|
|
|
footerHTMLString?: string | null
|
|
|
) => Promise<Blob | ArrayBuffer>
|
|
|
|
|
|
+/**
|
|
|
+ * html-to-docx(含 browser 包)在 Vite 二次打包后仍会直接读全局 Buffer/global。
|
|
|
+ * 必须在调用转换前注入,否则 buildImage 报 Buffer is not defined,随后 global is not defined。
|
|
|
+ */
|
|
|
+function ensureDocxNodeGlobals(): void {
|
|
|
+ const g = globalThis as typeof globalThis & {
|
|
|
+ Buffer?: typeof Buffer
|
|
|
+ global?: typeof globalThis
|
|
|
+ process?: { env?: Record<string, string | undefined> }
|
|
|
+ }
|
|
|
+ if (!g.Buffer) g.Buffer = Buffer
|
|
|
+ if (!g.global) g.global = g
|
|
|
+ if (!g.process) g.process = { env: {} }
|
|
|
+ else if (!g.process.env) g.process.env = {}
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* 懒加载 browser 构建。
|
|
|
- * Vite 默认会解析到 Node ESM(依赖 Buffer/global),浏览器会报错;
|
|
|
- * 顶层静态 import browser 包又会让 Node 单测因 XMLHttpRequest 初始化失败。
|
|
|
+ * Vite 默认会解析到 Node ESM(依赖 Buffer/global);显式 browser 入口 + 上方 globals 注入。
|
|
|
*/
|
|
|
async function loadHtmlToDocx(): Promise<HtmlToDocxFn> {
|
|
|
- const mod = await import('@turbodocx/html-to-docx/dist/html-to-docx.browser.esm.js')
|
|
|
+ ensureDocxNodeGlobals()
|
|
|
+ // 经 vite alias 指向 browser.esm.js
|
|
|
+ const mod = await import('@turbodocx/html-to-docx')
|
|
|
const candidate = typeof mod === 'function' ? mod : (mod as { default?: unknown }).default
|
|
|
if (typeof candidate !== 'function') {
|
|
|
throw new Error('html-to-docx 加载失败:未获得可调用的转换函数')
|
|
|
@@ -84,9 +103,11 @@ export async function generateContractDocxBlob(
|
|
|
preparedHtml: string,
|
|
|
title?: string
|
|
|
): Promise<Blob> {
|
|
|
+ ensureDocxNodeGlobals()
|
|
|
const HTMLtoDOCX = await loadHtmlToDocx()
|
|
|
const htmlWithImages = await inlineRemoteImagesAsDataUrls(preparedHtml)
|
|
|
const fullHtml = `<!DOCTYPE html><html><head><meta charset="UTF-8" /></head><body>${htmlWithImages}</body></html>`
|
|
|
+ ensureDocxNodeGlobals()
|
|
|
const result = await HTMLtoDOCX(fullHtml, null, {
|
|
|
orientation: 'portrait',
|
|
|
title: title || '合同',
|