|  | @@ -1,14 +1,11 @@
 | 
	
		
			
				|  |  | -import { ref } from 'vue'
 | 
	
		
			
				|  |  | -import { storeToRefs } from 'pinia'
 | 
	
		
			
				|  |  | -import { parse, type Shape, type Element, type ChartItem } from 'pptxtojson'
 | 
	
		
			
				|  |  | -import { nanoid } from 'nanoid'
 | 
	
		
			
				|  |  | -import { useSlidesStore } from '@/store'
 | 
	
		
			
				|  |  | -import { decrypt } from '@/utils/crypto'
 | 
	
		
			
				|  |  | -import { type ShapePoolItem, SHAPE_LIST, SHAPE_PATH_FORMULAS } from '@/configs/shapes'
 | 
	
		
			
				|  |  | -import useAddSlidesOrElements from '@/hooks/useAddSlidesOrElements'
 | 
	
		
			
				|  |  | -import useSlideHandler from '@/hooks/useSlideHandler'
 | 
	
		
			
				|  |  | -import message from '@/utils/message'
 | 
	
		
			
				|  |  | -import { getSvgPathRange } from '@/utils/svgPathParser'
 | 
	
		
			
				|  |  | +import { ref } from "vue"
 | 
	
		
			
				|  |  | +import { storeToRefs } from "pinia"
 | 
	
		
			
				|  |  | +import { parse, type Shape, type Element, type ChartItem } from "pptxtojson"
 | 
	
		
			
				|  |  | +import { nanoid } from "nanoid"
 | 
	
		
			
				|  |  | +import { useSlidesStore } from "@/store"
 | 
	
		
			
				|  |  | +import { type ShapePoolItem, SHAPE_LIST, SHAPE_PATH_FORMULAS } from "@/configs/shapes"
 | 
	
		
			
				|  |  | +import message from "@/utils/message"
 | 
	
		
			
				|  |  | +import { getSvgPathRange } from "@/utils/svgPathParser"
 | 
	
		
			
				|  |  |  import type {
 | 
	
		
			
				|  |  |    Slide,
 | 
	
		
			
				|  |  |    TableCellStyle,
 | 
	
	
		
			
				|  | @@ -19,8 +16,8 @@ import type {
 | 
	
		
			
				|  |  |    PPTLineElement,
 | 
	
		
			
				|  |  |    ShapeTextAlign,
 | 
	
		
			
				|  |  |    PPTTextElement,
 | 
	
		
			
				|  |  | -  ChartOptions,
 | 
	
		
			
				|  |  | -} from '@/types/slides'
 | 
	
		
			
				|  |  | +  ChartOptions
 | 
	
		
			
				|  |  | +} from "@/types/slides"
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  const convertFontSizePtToPx = (html: string, ratio: number) => {
 | 
	
		
			
				|  |  |    return html.replace(/font-size:\s*([\d.]+)pt/g, (match, p1) => {
 | 
	
	
		
			
				|  | @@ -32,56 +29,32 @@ export default () => {
 | 
	
		
			
				|  |  |    const slidesStore = useSlidesStore()
 | 
	
		
			
				|  |  |    const { theme } = storeToRefs(useSlidesStore())
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  const { addSlidesFromData } = useAddSlidesOrElements()
 | 
	
		
			
				|  |  | -  const { isEmptySlide } = useSlideHandler()
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |    const exporting = ref(false)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  // 导入pptist文件
 | 
	
		
			
				|  |  | -  const importSpecificFile = (files: FileList, cover = false) => {
 | 
	
		
			
				|  |  | -    const file = files[0]
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    const reader = new FileReader()
 | 
	
		
			
				|  |  | -    reader.addEventListener('load', () => {
 | 
	
		
			
				|  |  | -      try {
 | 
	
		
			
				|  |  | -        const slides = JSON.parse(decrypt(reader.result as string))
 | 
	
		
			
				|  |  | -        if (cover) {
 | 
	
		
			
				|  |  | -          slidesStore.updateSlideIndex(0)
 | 
	
		
			
				|  |  | -          slidesStore.setSlides(slides)
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        else if (isEmptySlide.value) slidesStore.setSlides(slides)
 | 
	
		
			
				|  |  | -        else addSlidesFromData(slides)
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -      catch {
 | 
	
		
			
				|  |  | -        message.error('无法正确读取 / 解析该文件')
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -    })
 | 
	
		
			
				|  |  | -    reader.readAsText(file)
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |    const parseLineElement = (el: Shape) => {
 | 
	
		
			
				|  |  |      let start: [number, number] = [0, 0]
 | 
	
		
			
				|  |  |      let end: [number, number] = [0, 0]
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    if (!el.isFlipV && !el.isFlipH) { // 右下
 | 
	
		
			
				|  |  | +    if (!el.isFlipV && !el.isFlipH) {
 | 
	
		
			
				|  |  | +      // 右下
 | 
	
		
			
				|  |  |        start = [0, 0]
 | 
	
		
			
				|  |  |        end = [el.width, el.height]
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    else if (el.isFlipV && el.isFlipH) { // 左上
 | 
	
		
			
				|  |  | +    } else if (el.isFlipV && el.isFlipH) {
 | 
	
		
			
				|  |  | +      // 左上
 | 
	
		
			
				|  |  |        start = [el.width, el.height]
 | 
	
		
			
				|  |  |        end = [0, 0]
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    else if (el.isFlipV && !el.isFlipH) { // 右上
 | 
	
		
			
				|  |  | +    } else if (el.isFlipV && !el.isFlipH) {
 | 
	
		
			
				|  |  | +      // 右上
 | 
	
		
			
				|  |  |        start = [0, el.height]
 | 
	
		
			
				|  |  |        end = [el.width, 0]
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    else { // 左下
 | 
	
		
			
				|  |  | +    } else {
 | 
	
		
			
				|  |  | +      // 左下
 | 
	
		
			
				|  |  |        start = [el.width, 0]
 | 
	
		
			
				|  |  |        end = [0, el.height]
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      const data: PPTLineElement = {
 | 
	
		
			
				|  |  | -      type: 'line',
 | 
	
		
			
				|  |  | +      type: "line",
 | 
	
		
			
				|  |  |        id: nanoid(10),
 | 
	
		
			
				|  |  |        width: el.borderWidth || 1,
 | 
	
		
			
				|  |  |        left: el.left,
 | 
	
	
		
			
				|  | @@ -90,13 +63,10 @@ export default () => {
 | 
	
		
			
				|  |  |        end,
 | 
	
		
			
				|  |  |        style: el.borderType,
 | 
	
		
			
				|  |  |        color: el.borderColor,
 | 
	
		
			
				|  |  | -      points: ['', /straightConnector/.test(el.shapType) ? 'arrow' : '']
 | 
	
		
			
				|  |  | +      points: ["", /straightConnector/.test(el.shapType) ? "arrow" : ""]
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      if (/bentConnector/.test(el.shapType)) {
 | 
	
		
			
				|  |  | -      data.broken2 = [
 | 
	
		
			
				|  |  | -        Math.abs(start[0] - end[0]) / 2,
 | 
	
		
			
				|  |  | -        Math.abs(start[1] - end[1]) / 2,
 | 
	
		
			
				|  |  | -      ]
 | 
	
		
			
				|  |  | +      data.broken2 = [Math.abs(start[0] - end[0]) / 2, Math.abs(start[1] - end[1]) / 2]
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      return data
 | 
	
	
		
			
				|  | @@ -113,7 +83,7 @@ export default () => {
 | 
	
		
			
				|  |  |      for (const item of SHAPE_LIST) {
 | 
	
		
			
				|  |  |        shapeList.push(...item.children)
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      const reader = new FileReader()
 | 
	
		
			
				|  |  |      reader.onload = async e => {
 | 
	
		
			
				|  |  |        const json = await parse(e.target!.result as ArrayBuffer)
 | 
	
	
		
			
				|  | @@ -127,39 +97,37 @@ export default () => {
 | 
	
		
			
				|  |  |        for (const item of json.slides) {
 | 
	
		
			
				|  |  |          const { type, value } = item.fill
 | 
	
		
			
				|  |  |          let background: SlideBackground
 | 
	
		
			
				|  |  | -        if (type === 'image') {
 | 
	
		
			
				|  |  | +        if (type === "image") {
 | 
	
		
			
				|  |  |            background = {
 | 
	
		
			
				|  |  | -            type: 'image',
 | 
	
		
			
				|  |  | +            type: "image",
 | 
	
		
			
				|  |  |              image: {
 | 
	
		
			
				|  |  |                src: value.picBase64,
 | 
	
		
			
				|  |  | -              size: 'cover',
 | 
	
		
			
				|  |  | -            },
 | 
	
		
			
				|  |  | +              size: "cover"
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  |            }
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        else if (type === 'gradient') {
 | 
	
		
			
				|  |  | +        } else if (type === "gradient") {
 | 
	
		
			
				|  |  |            background = {
 | 
	
		
			
				|  |  | -            type: 'gradient',
 | 
	
		
			
				|  |  | +            type: "gradient",
 | 
	
		
			
				|  |  |              gradient: {
 | 
	
		
			
				|  |  | -              type: 'linear',
 | 
	
		
			
				|  |  | +              type: "linear",
 | 
	
		
			
				|  |  |                colors: value.colors.map(item => ({
 | 
	
		
			
				|  |  |                  ...item,
 | 
	
		
			
				|  |  | -                pos: parseInt(item.pos),
 | 
	
		
			
				|  |  | +                pos: parseInt(item.pos)
 | 
	
		
			
				|  |  |                })),
 | 
	
		
			
				|  |  | -              rotate: value.rot,
 | 
	
		
			
				|  |  | -            },
 | 
	
		
			
				|  |  | +              rotate: value.rot
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  |            }
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        else {
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  |            background = {
 | 
	
		
			
				|  |  | -            type: 'solid',
 | 
	
		
			
				|  |  | -            color: value,
 | 
	
		
			
				|  |  | +            type: "solid",
 | 
	
		
			
				|  |  | +            color: value
 | 
	
		
			
				|  |  |            }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          const slide: Slide = {
 | 
	
		
			
				|  |  |            id: nanoid(10),
 | 
	
		
			
				|  |  |            elements: [],
 | 
	
		
			
				|  |  | -          background,
 | 
	
		
			
				|  |  | +          background
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          const parseElements = (elements: Element[]) => {
 | 
	
	
		
			
				|  | @@ -173,10 +141,10 @@ export default () => {
 | 
	
		
			
				|  |  |              el.height = el.height * ratio
 | 
	
		
			
				|  |  |              el.left = el.left * ratio
 | 
	
		
			
				|  |  |              el.top = el.top * ratio
 | 
	
		
			
				|  |  | -  
 | 
	
		
			
				|  |  | -            if (el.type === 'text') {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            if (el.type === "text") {
 | 
	
		
			
				|  |  |                const textEl: PPTTextElement = {
 | 
	
		
			
				|  |  | -                type: 'text',
 | 
	
		
			
				|  |  | +                type: "text",
 | 
	
		
			
				|  |  |                  id: nanoid(10),
 | 
	
		
			
				|  |  |                  width: el.width,
 | 
	
		
			
				|  |  |                  height: el.height,
 | 
	
	
		
			
				|  | @@ -190,24 +158,23 @@ export default () => {
 | 
	
		
			
				|  |  |                  outline: {
 | 
	
		
			
				|  |  |                    color: el.borderColor,
 | 
	
		
			
				|  |  |                    width: el.borderWidth,
 | 
	
		
			
				|  |  | -                  style: el.borderType,
 | 
	
		
			
				|  |  | +                  style: el.borderType
 | 
	
		
			
				|  |  |                  },
 | 
	
		
			
				|  |  |                  fill: el.fillColor,
 | 
	
		
			
				|  |  | -                vertical: el.isVertical,
 | 
	
		
			
				|  |  | +                vertical: el.isVertical
 | 
	
		
			
				|  |  |                }
 | 
	
		
			
				|  |  |                if (el.shadow) {
 | 
	
		
			
				|  |  |                  textEl.shadow = {
 | 
	
		
			
				|  |  |                    h: el.shadow.h * ratio,
 | 
	
		
			
				|  |  |                    v: el.shadow.v * ratio,
 | 
	
		
			
				|  |  |                    blur: el.shadow.blur * ratio,
 | 
	
		
			
				|  |  | -                  color: el.shadow.color,
 | 
	
		
			
				|  |  | +                  color: el.shadow.color
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |                }
 | 
	
		
			
				|  |  |                slide.elements.push(textEl)
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            else if (el.type === 'image') {
 | 
	
		
			
				|  |  | +            } else if (el.type === "image") {
 | 
	
		
			
				|  |  |                slide.elements.push({
 | 
	
		
			
				|  |  | -                type: 'image',
 | 
	
		
			
				|  |  | +                type: "image",
 | 
	
		
			
				|  |  |                  id: nanoid(10),
 | 
	
		
			
				|  |  |                  src: el.src,
 | 
	
		
			
				|  |  |                  width: el.width,
 | 
	
	
		
			
				|  | @@ -217,12 +184,11 @@ export default () => {
 | 
	
		
			
				|  |  |                  fixedRatio: true,
 | 
	
		
			
				|  |  |                  rotate: el.rotate,
 | 
	
		
			
				|  |  |                  flipH: el.isFlipH,
 | 
	
		
			
				|  |  | -                flipV: el.isFlipV,
 | 
	
		
			
				|  |  | +                flipV: el.isFlipV
 | 
	
		
			
				|  |  |                })
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            else if (el.type === 'audio') {
 | 
	
		
			
				|  |  | +            } else if (el.type === "audio") {
 | 
	
		
			
				|  |  |                slide.elements.push({
 | 
	
		
			
				|  |  | -                type: 'audio',
 | 
	
		
			
				|  |  | +                type: "audio",
 | 
	
		
			
				|  |  |                  id: nanoid(10),
 | 
	
		
			
				|  |  |                  src: el.blob,
 | 
	
		
			
				|  |  |                  width: el.width,
 | 
	
	
		
			
				|  | @@ -233,12 +199,11 @@ export default () => {
 | 
	
		
			
				|  |  |                  fixedRatio: false,
 | 
	
		
			
				|  |  |                  color: theme.value.themeColor,
 | 
	
		
			
				|  |  |                  loop: false,
 | 
	
		
			
				|  |  | -                autoplay: false,
 | 
	
		
			
				|  |  | +                autoplay: false
 | 
	
		
			
				|  |  |                })
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            else if (el.type === 'video') {
 | 
	
		
			
				|  |  | +            } else if (el.type === "video") {
 | 
	
		
			
				|  |  |                slide.elements.push({
 | 
	
		
			
				|  |  | -                type: 'video',
 | 
	
		
			
				|  |  | +                type: "video",
 | 
	
		
			
				|  |  |                  id: nanoid(10),
 | 
	
		
			
				|  |  |                  src: (el.blob || el.src)!,
 | 
	
		
			
				|  |  |                  width: el.width,
 | 
	
	
		
			
				|  | @@ -246,95 +211,91 @@ export default () => {
 | 
	
		
			
				|  |  |                  left: el.left,
 | 
	
		
			
				|  |  |                  top: el.top,
 | 
	
		
			
				|  |  |                  rotate: 0,
 | 
	
		
			
				|  |  | -                autoplay: false,
 | 
	
		
			
				|  |  | +                autoplay: false
 | 
	
		
			
				|  |  |                })
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            else if (el.type === 'shape') {
 | 
	
		
			
				|  |  | -              if (el.shapType === 'line' || /Connector/.test(el.shapType)) {
 | 
	
		
			
				|  |  | +            } else if (el.type === "shape") {
 | 
	
		
			
				|  |  | +              if (el.shapType === "line" || /Connector/.test(el.shapType)) {
 | 
	
		
			
				|  |  |                  const lineElement = parseLineElement(el)
 | 
	
		
			
				|  |  |                  slide.elements.push(lineElement)
 | 
	
		
			
				|  |  | -              }
 | 
	
		
			
				|  |  | -              else {
 | 
	
		
			
				|  |  | +              } else {
 | 
	
		
			
				|  |  |                  const shape = shapeList.find(item => item.pptxShapeType === el.shapType)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |                  const vAlignMap: { [key: string]: ShapeTextAlign } = {
 | 
	
		
			
				|  |  | -                  'mid': 'middle',
 | 
	
		
			
				|  |  | -                  'down': 'bottom',
 | 
	
		
			
				|  |  | -                  'up': 'top',
 | 
	
		
			
				|  |  | +                  mid: "middle",
 | 
	
		
			
				|  |  | +                  down: "bottom",
 | 
	
		
			
				|  |  | +                  up: "top"
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  | -                
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |                  const element: PPTShapeElement = {
 | 
	
		
			
				|  |  | -                  type: 'shape',
 | 
	
		
			
				|  |  | +                  type: "shape",
 | 
	
		
			
				|  |  |                    id: nanoid(10),
 | 
	
		
			
				|  |  |                    width: el.width,
 | 
	
		
			
				|  |  |                    height: el.height,
 | 
	
		
			
				|  |  |                    left: el.left,
 | 
	
		
			
				|  |  |                    top: el.top,
 | 
	
		
			
				|  |  |                    viewBox: [200, 200],
 | 
	
		
			
				|  |  | -                  path: 'M 0 0 L 200 0 L 200 200 L 0 200 Z',
 | 
	
		
			
				|  |  | -                  fill: el.fillColor || 'none',
 | 
	
		
			
				|  |  | +                  path: "M 0 0 L 200 0 L 200 200 L 0 200 Z",
 | 
	
		
			
				|  |  | +                  fill: el.fillColor || "none",
 | 
	
		
			
				|  |  |                    fixedRatio: false,
 | 
	
		
			
				|  |  |                    rotate: el.rotate,
 | 
	
		
			
				|  |  |                    outline: {
 | 
	
		
			
				|  |  |                      color: el.borderColor,
 | 
	
		
			
				|  |  |                      width: el.borderWidth,
 | 
	
		
			
				|  |  | -                    style: el.borderType,
 | 
	
		
			
				|  |  | +                    style: el.borderType
 | 
	
		
			
				|  |  |                    },
 | 
	
		
			
				|  |  |                    text: {
 | 
	
		
			
				|  |  |                      content: convertFontSizePtToPx(el.content, ratio),
 | 
	
		
			
				|  |  |                      defaultFontName: theme.value.fontName,
 | 
	
		
			
				|  |  |                      defaultColor: theme.value.fontColor,
 | 
	
		
			
				|  |  | -                    align: vAlignMap[el.vAlign] || 'middle',
 | 
	
		
			
				|  |  | +                    align: vAlignMap[el.vAlign] || "middle"
 | 
	
		
			
				|  |  |                    },
 | 
	
		
			
				|  |  |                    flipH: el.isFlipH,
 | 
	
		
			
				|  |  | -                  flipV: el.isFlipV,
 | 
	
		
			
				|  |  | +                  flipV: el.isFlipV
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |                  if (el.shadow) {
 | 
	
		
			
				|  |  |                    element.shadow = {
 | 
	
		
			
				|  |  |                      h: el.shadow.h * ratio,
 | 
	
		
			
				|  |  |                      v: el.shadow.v * ratio,
 | 
	
		
			
				|  |  |                      blur: el.shadow.blur * ratio,
 | 
	
		
			
				|  |  | -                    color: el.shadow.color,
 | 
	
		
			
				|  |  | +                    color: el.shadow.color
 | 
	
		
			
				|  |  |                    }
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |                  if (shape) {
 | 
	
		
			
				|  |  |                    element.path = shape.path
 | 
	
		
			
				|  |  |                    element.viewBox = shape.viewBox
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |                    if (shape.pathFormula) {
 | 
	
		
			
				|  |  |                      element.pathFormula = shape.pathFormula
 | 
	
		
			
				|  |  |                      element.viewBox = [el.width, el.height]
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |                      const pathFormula = SHAPE_PATH_FORMULAS[shape.pathFormula]
 | 
	
		
			
				|  |  | -                    if ('editable' in pathFormula && pathFormula.editable) {
 | 
	
		
			
				|  |  | +                    if ("editable" in pathFormula && pathFormula.editable) {
 | 
	
		
			
				|  |  |                        element.path = pathFormula.formula(el.width, el.height, pathFormula.defaultValue)
 | 
	
		
			
				|  |  |                        element.keypoints = pathFormula.defaultValue
 | 
	
		
			
				|  |  | -                    }
 | 
	
		
			
				|  |  | -                    else element.path = pathFormula.formula(el.width, el.height)
 | 
	
		
			
				|  |  | +                    } else element.path = pathFormula.formula(el.width, el.height)
 | 
	
		
			
				|  |  |                    }
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  | -                if (el.shapType === 'custom') {
 | 
	
		
			
				|  |  | -                  if (el.path!.indexOf('NaN') !== -1) element.path = ''
 | 
	
		
			
				|  |  | +                if (el.shapType === "custom") {
 | 
	
		
			
				|  |  | +                  if (el.path!.indexOf("NaN") !== -1) element.path = ""
 | 
	
		
			
				|  |  |                    else {
 | 
	
		
			
				|  |  |                      element.special = true
 | 
	
		
			
				|  |  |                      element.path = el.path!
 | 
	
		
			
				|  |  | -  
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |                      const { maxX, maxY } = getSvgPathRange(element.path)
 | 
	
		
			
				|  |  |                      element.viewBox = [maxX || originWidth, maxY || originHeight]
 | 
	
		
			
				|  |  |                    }
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |                  if (element.path) slide.elements.push(element)
 | 
	
		
			
				|  |  |                }
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            else if (el.type === 'table') {
 | 
	
		
			
				|  |  | +            } else if (el.type === "table") {
 | 
	
		
			
				|  |  |                const row = el.data.length
 | 
	
		
			
				|  |  |                const col = el.data[0].length
 | 
	
		
			
				|  |  | -  
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |                const style: TableCellStyle = {
 | 
	
		
			
				|  |  |                  fontname: theme.value.fontName,
 | 
	
		
			
				|  |  | -                color: theme.value.fontColor,
 | 
	
		
			
				|  |  | +                color: theme.value.fontColor
 | 
	
		
			
				|  |  |                }
 | 
	
		
			
				|  |  |                const data: TableCell[][] = []
 | 
	
		
			
				|  |  |                for (let i = 0; i < row; i++) {
 | 
	
	
		
			
				|  | @@ -342,14 +303,14 @@ export default () => {
 | 
	
		
			
				|  |  |                  for (let j = 0; j < col; j++) {
 | 
	
		
			
				|  |  |                    const cellData = el.data[i][j]
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -                  let textDiv: HTMLDivElement | null = document.createElement('div')
 | 
	
		
			
				|  |  | +                  let textDiv: HTMLDivElement | null = document.createElement("div")
 | 
	
		
			
				|  |  |                    textDiv.innerHTML = cellData.text
 | 
	
		
			
				|  |  | -                  const p = textDiv.querySelector('p')
 | 
	
		
			
				|  |  | -                  const align = p?.style.textAlign || 'left'
 | 
	
		
			
				|  |  | +                  const p = textDiv.querySelector("p")
 | 
	
		
			
				|  |  | +                  const align = p?.style.textAlign || "left"
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -                  const span = textDiv.querySelector('span')
 | 
	
		
			
				|  |  | -                  const fontsize = span?.style.fontSize ? (parseInt(span?.style.fontSize) * ratio).toFixed(1) + 'px' : ''
 | 
	
		
			
				|  |  | -                  const fontname = span?.style.fontFamily || ''
 | 
	
		
			
				|  |  | +                  const span = textDiv.querySelector("span")
 | 
	
		
			
				|  |  | +                  const fontsize = span?.style.fontSize ? (parseInt(span?.style.fontSize) * ratio).toFixed(1) + "px" : ""
 | 
	
		
			
				|  |  | +                  const fontname = span?.style.fontFamily || ""
 | 
	
		
			
				|  |  |                    const color = span?.style.color || cellData.fontColor
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |                    rowCells.push({
 | 
	
	
		
			
				|  | @@ -359,23 +320,23 @@ export default () => {
 | 
	
		
			
				|  |  |                      text: textDiv.innerText,
 | 
	
		
			
				|  |  |                      style: {
 | 
	
		
			
				|  |  |                        ...style,
 | 
	
		
			
				|  |  | -                      align: ['left', 'right', 'center'].includes(align) ? (align as 'left' | 'right' | 'center') : 'left',
 | 
	
		
			
				|  |  | +                      align: ["left", "right", "center"].includes(align) ? (align as "left" | "right" | "center") : "left",
 | 
	
		
			
				|  |  |                        fontsize,
 | 
	
		
			
				|  |  |                        fontname,
 | 
	
		
			
				|  |  |                        color,
 | 
	
		
			
				|  |  |                        bold: cellData.fontBold,
 | 
	
		
			
				|  |  | -                      backcolor: cellData.fillColor,
 | 
	
		
			
				|  |  | -                    },
 | 
	
		
			
				|  |  | +                      backcolor: cellData.fillColor
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  |                    })
 | 
	
		
			
				|  |  |                    textDiv = null
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |                  data.push(rowCells)
 | 
	
		
			
				|  |  |                }
 | 
	
		
			
				|  |  | -  
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |                const colWidths: number[] = new Array(col).fill(1 / col)
 | 
	
		
			
				|  |  | -  
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |                slide.elements.push({
 | 
	
		
			
				|  |  | -                type: 'table',
 | 
	
		
			
				|  |  | +                type: "table",
 | 
	
		
			
				|  |  |                  id: nanoid(10),
 | 
	
		
			
				|  |  |                  width: el.width,
 | 
	
		
			
				|  |  |                  height: el.height,
 | 
	
	
		
			
				|  | @@ -387,22 +348,20 @@ export default () => {
 | 
	
		
			
				|  |  |                  outline: {
 | 
	
		
			
				|  |  |                    width: el.borderWidth || 2,
 | 
	
		
			
				|  |  |                    style: el.borderType,
 | 
	
		
			
				|  |  | -                  color: el.borderColor || '#eeece1',
 | 
	
		
			
				|  |  | +                  color: el.borderColor || "#eeece1"
 | 
	
		
			
				|  |  |                  },
 | 
	
		
			
				|  |  | -                cellMinHeight: 36,
 | 
	
		
			
				|  |  | +                cellMinHeight: 36
 | 
	
		
			
				|  |  |                })
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            else if (el.type === 'chart') {
 | 
	
		
			
				|  |  | +            } else if (el.type === "chart") {
 | 
	
		
			
				|  |  |                let labels: string[]
 | 
	
		
			
				|  |  |                let legends: string[]
 | 
	
		
			
				|  |  |                let series: number[][]
 | 
	
		
			
				|  |  | -  
 | 
	
		
			
				|  |  | -              if (el.chartType === 'scatterChart' || el.chartType === 'bubbleChart') {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +              if (el.chartType === "scatterChart" || el.chartType === "bubbleChart") {
 | 
	
		
			
				|  |  |                  labels = el.data[0].map((item, index) => `坐标${index + 1}`)
 | 
	
		
			
				|  |  | -                legends = ['X', 'Y']
 | 
	
		
			
				|  |  | +                legends = ["X", "Y"]
 | 
	
		
			
				|  |  |                  series = el.data
 | 
	
		
			
				|  |  | -              }
 | 
	
		
			
				|  |  | -              else {
 | 
	
		
			
				|  |  | +              } else {
 | 
	
		
			
				|  |  |                  const data = el.data as ChartItem[]
 | 
	
		
			
				|  |  |                  labels = Object.values(data[0].xlabels)
 | 
	
		
			
				|  |  |                  legends = data.map(item => item.key)
 | 
	
	
		
			
				|  | @@ -410,45 +369,45 @@ export default () => {
 | 
	
		
			
				|  |  |                }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |                const options: ChartOptions = {}
 | 
	
		
			
				|  |  | -  
 | 
	
		
			
				|  |  | -              let chartType: ChartType = 'bar'
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +              let chartType: ChartType = "bar"
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |                switch (el.chartType) {
 | 
	
		
			
				|  |  | -                case 'barChart':
 | 
	
		
			
				|  |  | -                case 'bar3DChart':
 | 
	
		
			
				|  |  | -                  chartType = 'bar'
 | 
	
		
			
				|  |  | -                  if (el.barDir === 'bar') chartType = 'column'
 | 
	
		
			
				|  |  | -                  if (el.grouping === 'stacked' || el.grouping === 'percentStacked') options.stack = true
 | 
	
		
			
				|  |  | +                case "barChart":
 | 
	
		
			
				|  |  | +                case "bar3DChart":
 | 
	
		
			
				|  |  | +                  chartType = "bar"
 | 
	
		
			
				|  |  | +                  if (el.barDir === "bar") chartType = "column"
 | 
	
		
			
				|  |  | +                  if (el.grouping === "stacked" || el.grouping === "percentStacked") options.stack = true
 | 
	
		
			
				|  |  |                    break
 | 
	
		
			
				|  |  | -                case 'lineChart':
 | 
	
		
			
				|  |  | -                case 'line3DChart':
 | 
	
		
			
				|  |  | -                  if (el.grouping === 'stacked' || el.grouping === 'percentStacked') options.stack = true
 | 
	
		
			
				|  |  | -                  chartType = 'line'
 | 
	
		
			
				|  |  | +                case "lineChart":
 | 
	
		
			
				|  |  | +                case "line3DChart":
 | 
	
		
			
				|  |  | +                  if (el.grouping === "stacked" || el.grouping === "percentStacked") options.stack = true
 | 
	
		
			
				|  |  | +                  chartType = "line"
 | 
	
		
			
				|  |  |                    break
 | 
	
		
			
				|  |  | -                case 'areaChart':
 | 
	
		
			
				|  |  | -                case 'area3DChart':
 | 
	
		
			
				|  |  | -                  if (el.grouping === 'stacked' || el.grouping === 'percentStacked') options.stack = true
 | 
	
		
			
				|  |  | -                  chartType = 'area'
 | 
	
		
			
				|  |  | +                case "areaChart":
 | 
	
		
			
				|  |  | +                case "area3DChart":
 | 
	
		
			
				|  |  | +                  if (el.grouping === "stacked" || el.grouping === "percentStacked") options.stack = true
 | 
	
		
			
				|  |  | +                  chartType = "area"
 | 
	
		
			
				|  |  |                    break
 | 
	
		
			
				|  |  | -                case 'scatterChart':
 | 
	
		
			
				|  |  | -                case 'bubbleChart':
 | 
	
		
			
				|  |  | -                  chartType = 'scatter'
 | 
	
		
			
				|  |  | +                case "scatterChart":
 | 
	
		
			
				|  |  | +                case "bubbleChart":
 | 
	
		
			
				|  |  | +                  chartType = "scatter"
 | 
	
		
			
				|  |  |                    break
 | 
	
		
			
				|  |  | -                case 'pieChart':
 | 
	
		
			
				|  |  | -                case 'pie3DChart':
 | 
	
		
			
				|  |  | -                  chartType = 'pie'
 | 
	
		
			
				|  |  | +                case "pieChart":
 | 
	
		
			
				|  |  | +                case "pie3DChart":
 | 
	
		
			
				|  |  | +                  chartType = "pie"
 | 
	
		
			
				|  |  |                    break
 | 
	
		
			
				|  |  | -                case 'radarChart':
 | 
	
		
			
				|  |  | -                  chartType = 'radar'
 | 
	
		
			
				|  |  | +                case "radarChart":
 | 
	
		
			
				|  |  | +                  chartType = "radar"
 | 
	
		
			
				|  |  |                    break
 | 
	
		
			
				|  |  | -                case 'doughnutChart':
 | 
	
		
			
				|  |  | -                  chartType = 'ring'
 | 
	
		
			
				|  |  | +                case "doughnutChart":
 | 
	
		
			
				|  |  | +                  chartType = "ring"
 | 
	
		
			
				|  |  |                    break
 | 
	
		
			
				|  |  |                  default:
 | 
	
		
			
				|  |  |                }
 | 
	
		
			
				|  |  | -  
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |                slide.elements.push({
 | 
	
		
			
				|  |  | -                type: 'chart',
 | 
	
		
			
				|  |  | +                type: "chart",
 | 
	
		
			
				|  |  |                  id: nanoid(10),
 | 
	
		
			
				|  |  |                  chartType: chartType,
 | 
	
		
			
				|  |  |                  width: el.width,
 | 
	
	
		
			
				|  | @@ -461,16 +420,15 @@ export default () => {
 | 
	
		
			
				|  |  |                  data: {
 | 
	
		
			
				|  |  |                    labels,
 | 
	
		
			
				|  |  |                    legends,
 | 
	
		
			
				|  |  | -                  series,
 | 
	
		
			
				|  |  | +                  series
 | 
	
		
			
				|  |  |                  },
 | 
	
		
			
				|  |  | -                options,
 | 
	
		
			
				|  |  | +                options
 | 
	
		
			
				|  |  |                })
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            else if (el.type === 'group' || el.type === 'diagram') {
 | 
	
		
			
				|  |  | +            } else if (el.type === "group" || el.type === "diagram") {
 | 
	
		
			
				|  |  |                const elements = el.elements.map(_el => ({
 | 
	
		
			
				|  |  |                  ..._el,
 | 
	
		
			
				|  |  |                  left: _el.left + originLeft,
 | 
	
		
			
				|  |  | -                top: _el.top + originTop,
 | 
	
		
			
				|  |  | +                top: _el.top + originTop
 | 
	
		
			
				|  |  |                }))
 | 
	
		
			
				|  |  |                parseElements(elements)
 | 
	
		
			
				|  |  |              }
 | 
	
	
		
			
				|  | @@ -487,8 +445,7 @@ export default () => {
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    return {
 | 
	
		
			
				|  |  | -    importSpecificFile,
 | 
	
		
			
				|  |  |      importPPTXFile,
 | 
	
		
			
				|  |  | -    exporting,
 | 
	
		
			
				|  |  | +    exporting
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | +}
 |