From 3b68b06614ffc1ae683273c132d920aeb3ea334d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=82=93=E4=BA=AE?= <787615673@qq.com> Date: Thu, 25 Dec 2025 14:58:23 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat(export-docx):=20=E6=94=AF=E6=8C=81webp?= =?UTF-8?q?=E5=9B=BE=E7=89=87=E6=A0=BC=E5=BC=8F=E5=B9=B6=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E5=9B=BE=E7=89=87=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加对webp图片格式的支持,包括类型检测和转换处理 优化图片宽高获取逻辑,增加类型检查和空值处理 改进图片数据获取,添加重定向和超时处理 修复(intermediate value).bytes is not a function at W (index.mjs:1:3196) 这个问题 --- packages/export-docx/src/converters/image.ts | 8 +++- packages/export-docx/src/utils.ts | 45 +++++++++++++++----- 2 files changed, 41 insertions(+), 12 deletions(-) diff --git a/packages/export-docx/src/converters/image.ts b/packages/export-docx/src/converters/image.ts index b281acb..31ef8ea 100644 --- a/packages/export-docx/src/converters/image.ts +++ b/packages/export-docx/src/converters/image.ts @@ -21,7 +21,9 @@ export async function convertImage( options: DocxOptions["image"], ): Promise { // Get image type from metadata or URL - const getImageType = (metaType?: string): "jpg" | "png" | "gif" | "bmp" => { + const getImageType = ( + metaType?: string, + ): "jpg" | "png" | "gif" | "bmp" | "webp" => { // Try metadata type first switch (metaType) { case "jpeg": @@ -33,6 +35,8 @@ export async function convertImage( return "gif"; case "bmp": return "bmp"; + case "webp": + return "png"; } // Fallback to URL-based type detection @@ -46,6 +50,8 @@ export async function convertImage( return "gif"; case "bmp": return "bmp"; + case "webp": + return "png"; default: return "png"; } diff --git a/packages/export-docx/src/utils.ts b/packages/export-docx/src/utils.ts index d7ca9d2..36830d2 100644 --- a/packages/export-docx/src/utils.ts +++ b/packages/export-docx/src/utils.ts @@ -10,7 +10,7 @@ import { ofetch } from "ofetch"; */ export function getImageTypeFromSrc( src: string, -): "png" | "jpeg" | "gif" | "bmp" | "tiff" { +): "png" | "jpeg" | "gif" | "bmp" | "tiff" | "webp" { if (src.startsWith("data:")) { const match = src.match(/data:image\/(\w+);/); if (match) { @@ -27,6 +27,8 @@ export function getImageTypeFromSrc( return "bmp"; case "tiff": return "tiff"; + case "webp": + return "webp"; default: return "png"; } @@ -45,6 +47,8 @@ export function getImageTypeFromSrc( return "bmp"; case "tiff": return "tiff"; + case "webp": + return "webp"; default: return "png"; } @@ -77,12 +81,17 @@ export function createFloatingOptions() { export function getImageWidth( node: { attrs?: { width?: number | null } }, options?: { run?: { transformation?: { width?: number } } }, - imageMeta?: { width?: number }, + imageMeta?: { width?: number | null }, ): number { - if (node.attrs?.width) return node.attrs.width; - if (options?.run?.transformation?.width) + if (node.attrs?.width && typeof node.attrs.width === "number") { + return node.attrs.width; + } + if (options?.run?.transformation?.width) { return options.run.transformation.width; - if (imageMeta?.width) return Math.min(imageMeta.width, 600); + } + if (imageMeta?.width && typeof imageMeta.width === "number") { + return Math.min(imageMeta.width, 600); + } return 400; } @@ -93,13 +102,22 @@ export function getImageHeight( node: { attrs?: { height?: number | null } }, width: number, options?: { run?: { transformation?: { height?: number } } }, - imageMeta?: { width?: number; height?: number }, + imageMeta?: { width?: number | null; height?: number | null }, ): number { - if (node.attrs?.height) return node.attrs.height; - if (options?.run?.transformation?.height) + if (node.attrs?.height && typeof node.attrs.height === "number") { + return node.attrs.height; + } + if (options?.run?.transformation?.height) { return options.run.transformation.height; - if (imageMeta?.width && imageMeta?.height) + } + if ( + imageMeta?.width && + typeof imageMeta.width === "number" && + imageMeta?.height && + typeof imageMeta.height === "number" + ) { return Math.round((width * imageMeta.height) / imageMeta.width); + } return 300; } @@ -111,8 +129,13 @@ export async function getImageDataAndMeta( ): Promise<{ data: Uint8Array; meta: ImageMeta }> { try { // Use ofetch to get binary data with responseType: "blob" - const blob = await ofetch(url, { responseType: "blob" }); - const data = await blob.bytes(); + const blob = await ofetch(url, { + responseType: "blob", + redirect: "follow", + timeout: 30000, + }); + const arrayBuffer = await blob.arrayBuffer(); + const data = new Uint8Array(arrayBuffer); // Get image metadata using image-meta let meta: ImageMeta; From 4c12856ad435dc4d0f0ab2e0868cfda48dd0f812 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=82=93=E4=BA=AE?= <787615673@qq.com> Date: Fri, 26 Dec 2025 15:45:50 +0800 Subject: [PATCH 2/2] =?UTF-8?q?fix(export-docx):=20=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E5=9B=BE=E7=89=87=E5=B0=BA=E5=AF=B8=E8=AE=A1=E7=AE=97=E9=80=BB?= =?UTF-8?q?=E8=BE=91=EF=BC=8C=E9=81=BF=E5=85=8D=E8=BF=87=E5=B0=8F=E5=9B=BE?= =?UTF-8?q?=E7=89=87=E6=98=BE=E7=A4=BA=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 当图片宽度或高度计算值过小时,使用默认尺寸替代,确保图片显示清晰可见 --- packages/export-docx/src/utils.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/export-docx/src/utils.ts b/packages/export-docx/src/utils.ts index 36830d2..4145de3 100644 --- a/packages/export-docx/src/utils.ts +++ b/packages/export-docx/src/utils.ts @@ -90,7 +90,9 @@ export function getImageWidth( return options.run.transformation.width; } if (imageMeta?.width && typeof imageMeta.width === "number") { - return Math.min(imageMeta.width, 600); + const width = Math.min(imageMeta.width, 600); + // 如果图片太小,使用默认尺寸 + return width < 50 ? 400 : width; } return 400; } @@ -116,7 +118,9 @@ export function getImageHeight( imageMeta?.height && typeof imageMeta.height === "number" ) { - return Math.round((width * imageMeta.height) / imageMeta.width); + const height = Math.round((width * imageMeta.height) / imageMeta.width); + // 如果计算出的高度太小,使用默认尺寸 + return height < 50 ? 300 : height; } return 300; }