Browse Source

feat: 增加对ppt和pdf文件的导入转换支持

为useImport钩子添加了ppt和pdf文件的转换逻辑,通过ConvertAPI将这两种格式先转换为pptx后再进行导入处理。
lsc 2 weeks ago
parent
commit
4f99bee9f9
1 changed files with 54 additions and 3 deletions
  1. 54 3
      src/hooks/useImport.ts

+ 54 - 3
src/hooks/useImport.ts

@@ -1,4 +1,4 @@
-import { ref, nextTick } from 'vue'
+import { ref, nextTick } from 'vue'
 import { storeToRefs } from 'pinia'
 import { parse, type Shape, type Element, type ChartItem, type BaseElement } from 'pptxtojson'
 import { nanoid } from 'nanoid'
@@ -923,9 +923,60 @@ export default () => {
     const file = files[0]
     if (!file) return
 
-    exporting.value = true
-    imgExporting.value = true
+    // ppt / pdf 文件先通过 convertapi 转为 pptx
+    const fileName = file.name.toLowerCase()
+    const needConvert = fileName.endsWith('.ppt') || fileName.endsWith('.pdf')
+    if (needConvert) {
+      const fromFormat = fileName.endsWith('.ppt') ? 'ppt' : 'pdf'
+      const secret = 'UQB8F8GjADHxXfW544FmAl0qb3EsIkDO'
+      exporting.value = true
+      imgExporting.value = true
+      startTimer?.()
+      const oneHour = 60 * 60 * 1000
+      // 1. 上传文件到 ConvertAPI
+      fetch(`https://v2.convertapi.com/upload?filename=${encodeURIComponent(file.name)}`, {
+        method: 'POST',
+        body: file,
+        signal: AbortSignal.timeout(oneHour),
+      })
+        .then(r => r.json())
+        .then(uploadRes => {
+          if (!uploadRes.FileId) throw new Error('文件上传失败')
+          // 2. 调用转换接口
+          const body = { Parameters: [{ Name: 'File', FileValue: { Id: uploadRes.FileId } }] }
+          return fetch(`https://v2.convertapi.com/convert/${fromFormat}/to/pptx?secret=${secret}&StoreFile=true`, {
+            method: 'POST',
+            headers: { 'Content-Type': 'application/json' },
+            body: JSON.stringify(body),
+            signal: AbortSignal.timeout(oneHour),
+          }).then(r => r.json())
+        })
+        .then(convRes => {
+          const fileUrl = convRes?.Files?.[0]?.Url
+          console.log('转换成功:', fileUrl)
+          if (!fileUrl) throw new Error('转换失败:未获取到文件')
+          return fetch(fileUrl, { signal: AbortSignal.timeout(oneHour) })
+        })
+        .then(res => res.arrayBuffer())
+        .then(buffer => {
+          const convertedFile = new File([buffer], file.name.replace(/\.(ppt|pdf)$/i, '.pptx'), { type: 'application/vnd.openxmlformats-officedocument.presentationml.presentation' })
+          const dt = new DataTransfer()
+          dt.items.add(convertedFile)
+          importPPTXFile(dt.files, options)
+        })
+        .catch((err: any) => {
+          console.error('转换失败:', err)
+          message.error(lang.ssFileReadFail)
+          exporting.value = false
+          imgExporting.value = false
+        })
+      return
+    }
+
+    exporting.value = true // 假设 exporting 是一个全局 ref
+    imgExporting.value = true // 假设 imgExporting 是一个全局 ref
     startTimer?.()
+    // 预加载形状库(用于后续形状匹配)
     const shapeList: ShapePoolItem[] = []
     for (const item of SHAPE_LIST) {
       shapeList.push(...item.children)