import { Document, Packer, Paragraph, ImageRun, TextRun, HeadingLevel } from "docx" interface Screenshot { id: string name: string url: string dataUrl?: string timestamp: Date status: string } interface DocumentSettings { title: string author: string description: string includeTimestamp: boolean includePageUrls: boolean imageFormat: string imageQuality: number pageSize: string orientation: string } export async function generateDocx(screenshots: Screenshot[], settings: DocumentSettings): Promise { try { const children: Paragraph[] = [] // 添加标题 children.push( new Paragraph({ children: [ new TextRun({ text: settings.title, bold: true, size: 32, }), ], heading: HeadingLevel.TITLE, }), ) // 添加描述 if (settings.description) { children.push( new Paragraph({ children: [ new TextRun({ text: settings.description, size: 24, }), ], }), ) } // 添加生成信息 if (settings.includeTimestamp) { children.push( new Paragraph({ children: [ new TextRun({ text: `生成时间: ${new Date().toLocaleString()}`, size: 20, italics: true, }), ], }), ) } children.push( new Paragraph({ children: [ new TextRun({ text: `作者: ${settings.author}`, size: 20, italics: true, }), ], }), ) // 添加分隔符 children.push( new Paragraph({ children: [ new TextRun({ text: "─".repeat(50), size: 20, }), ], }), ) // 添加每个截图 for (const screenshot of screenshots) { // 页面标题 children.push( new Paragraph({ children: [ new TextRun({ text: screenshot.name, bold: true, size: 28, }), ], heading: HeadingLevel.HEADING_1, }), ) // 页面URL if (settings.includePageUrls) { children.push( new Paragraph({ children: [ new TextRun({ text: `页面地址: ${screenshot.url}`, size: 20, color: "666666", }), ], }), ) } // 截图时间 if (settings.includeTimestamp) { children.push( new Paragraph({ children: [ new TextRun({ text: `截图时间: ${screenshot.timestamp.toLocaleString()}`, size: 20, color: "666666", }), ], }), ) } // 添加截图 if (screenshot.dataUrl) { try { // 将 dataUrl 转换为 ArrayBuffer const base64Data = screenshot.dataUrl.split(",")[1] const binaryString = atob(base64Data) const bytes = new Uint8Array(binaryString.length) for (let i = 0; i < binaryString.length; i++) { bytes[i] = binaryString.charCodeAt(i) } children.push( new Paragraph({ children: [ new ImageRun({ data: bytes, transformation: { width: 600, height: 400, }, }), ], }), ) } catch (error) { console.error("添加图片失败:", error) children.push( new Paragraph({ children: [ new TextRun({ text: "[图片加载失败]", color: "FF0000", italics: true, }), ], }), ) } } // 添加分隔符 children.push( new Paragraph({ children: [ new TextRun({ text: "", }), ], }), ) } // 创建文档 const doc = new Document({ sections: [ { properties: {}, children: children, }, ], }) // 生成文档 const buffer = await Packer.toBuffer(doc) return buffer } catch (error) { console.error("生成文档失败:", error) throw new Error(`文档生成失败: ${error instanceof Error ? error.message : "未知错误"}`) } }