|
|
@@ -83,20 +83,71 @@ const WordMergePage: React.FC = () => {
|
|
|
|
|
|
setIsMerging(true);
|
|
|
try {
|
|
|
- // 这里使用简单的模拟合并,实际项目中需要调用后端API或使用前端库
|
|
|
- // 由于Word文档合并需要复杂的处理,这里使用模拟方式
|
|
|
+ // 使用真实的Word文档合并功能
|
|
|
+ // 加载必要的库
|
|
|
+ const PizZip = (await import('pizzip')).default;
|
|
|
+ const JSZip = (await import('jszip')).default;
|
|
|
|
|
|
- // 模拟合并过程
|
|
|
- await new Promise(resolve => setTimeout(resolve, 2000));
|
|
|
+ if (files.length === 0) {
|
|
|
+ toast.error('请先选择要合并的Word文档');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 使用第一个文档作为基础模板
|
|
|
+ const baseFile = files[0].file;
|
|
|
+ const baseArrayBuffer = await baseFile.arrayBuffer();
|
|
|
+ const baseZip = new PizZip(baseArrayBuffer);
|
|
|
+
|
|
|
+ // 创建一个新的JSZip实例来合并内容
|
|
|
+ const mergedZip = new JSZip();
|
|
|
+
|
|
|
+ // 加载基础文档
|
|
|
+ const baseDocx = await mergedZip.loadAsync(baseArrayBuffer);
|
|
|
+
|
|
|
+ // 获取基础文档的word/document.xml内容,使用arrayBuffer避免编码问题
|
|
|
+ const baseXmlArrayBuffer = await baseDocx.file('word/document.xml').async('arraybuffer');
|
|
|
+ const textDecoder = new TextDecoder('utf-8');
|
|
|
+ let mergedContent = textDecoder.decode(baseXmlArrayBuffer);
|
|
|
+
|
|
|
+ // 移除基础文档的结束标签,以便添加其他文档内容
|
|
|
+ mergedContent = mergedContent.replace(/<\/w:body>\s*<\/w:document>\s*$/, '');
|
|
|
+
|
|
|
+ // 逐个添加其他文档的内容(从第二个文件开始)
|
|
|
+ for (let i = 1; i < files.length; i++) {
|
|
|
+ const file = files[i].file;
|
|
|
+ const fileArrayBuffer = await file.arrayBuffer();
|
|
|
+ const fileZip = await mergedZip.loadAsync(fileArrayBuffer);
|
|
|
+ const fileXmlArrayBuffer = await fileZip.file('word/document.xml').async('arraybuffer');
|
|
|
+ let fileContent = textDecoder.decode(fileXmlArrayBuffer);
|
|
|
+
|
|
|
+ // 提取文档主体内容
|
|
|
+ const bodyMatch = fileContent.match(/<w:body(?:\s+[^>]*)?>([\s\S]*?)<\/w:body>/);
|
|
|
+ if (bodyMatch && bodyMatch[1]) {
|
|
|
+ mergedContent += bodyMatch[1];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 添加完整的结束标签,确保XML结构完整
|
|
|
+ mergedContent += '</w:body></w:document>';
|
|
|
+
|
|
|
+ // 确保XML声明和编码正确
|
|
|
+ if (!mergedContent.startsWith('<?xml')) {
|
|
|
+ mergedContent = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' + mergedContent;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新合并后的内容
|
|
|
+ baseDocx.file('word/document.xml', mergedContent);
|
|
|
|
|
|
- // 创建一个模拟的合并后的Blob对象
|
|
|
- const mergedContent = new Blob(
|
|
|
- [new Uint8Array([0x50, 0x4B, 0x03, 0x04])], // 模拟DOCX文件头
|
|
|
- { type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' }
|
|
|
- );
|
|
|
+ // 生成合并后的Word文档
|
|
|
+ const mergedDoc = await baseDocx.generateAsync({
|
|
|
+ type: 'blob',
|
|
|
+ mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
|
+ compression: 'DEFLATE',
|
|
|
+ compressionOptions: { level: 6 }
|
|
|
+ });
|
|
|
|
|
|
- setMergedFile(mergedContent);
|
|
|
- toast.success('文档合并成功!');
|
|
|
+ setMergedFile(mergedDoc);
|
|
|
+ toast.success(`已成功合并 ${files.length} 个Word文档为一个文件`);
|
|
|
} catch (error) {
|
|
|
console.error('合并失败:', error);
|
|
|
toast.error('文档合并失败,请重试');
|