|
@@ -1,18 +1,18 @@
|
|
|
-import { computed, ref } from 'vue'
|
|
|
-import { storeToRefs } from 'pinia'
|
|
|
-import { trim } from 'lodash'
|
|
|
-import { saveAs } from 'file-saver'
|
|
|
-import pptxgen from 'pptxgenjs'
|
|
|
-import tinycolor from 'tinycolor2'
|
|
|
-import { toPng, toJpeg } from 'html-to-image'
|
|
|
-import { useSlidesStore } from '@/store'
|
|
|
-import type { PPTElementOutline, PPTElementShadow, PPTElementLink, Slide } from '@/types/slides'
|
|
|
-import { getElementRange, getLineElementPath, getTableSubThemeColor } from '@/utils/element'
|
|
|
-import { type AST, toAST } from '@/utils/htmlParser'
|
|
|
-import { type SvgPoints, toPoints } from '@/utils/svgPathParser'
|
|
|
-import { encrypt } from '@/utils/crypto'
|
|
|
-import { svg2Base64 } from '@/utils/svg2Base64'
|
|
|
-import message from '@/utils/message'
|
|
|
+import { computed, ref } from "vue"
|
|
|
+import { storeToRefs } from "pinia"
|
|
|
+import { trim } from "lodash"
|
|
|
+import { saveAs } from "file-saver"
|
|
|
+import pptxgen from "pptxgenjs"
|
|
|
+import tinycolor from "tinycolor2"
|
|
|
+import { toPng, toJpeg } from "html-to-image"
|
|
|
+import { useSlidesStore } from "@/store"
|
|
|
+import type { PPTElementOutline, PPTElementShadow, PPTElementLink, Slide } from "@/types/slides"
|
|
|
+import { getElementRange, getLineElementPath, getTableSubThemeColor } from "@/utils/element"
|
|
|
+import { type AST, toAST } from "@/utils/htmlParser"
|
|
|
+import { type SvgPoints, toPoints } from "@/utils/svgPathParser"
|
|
|
+import { encrypt } from "@/utils/crypto"
|
|
|
+import { svg2Base64 } from "@/utils/svg2Base64"
|
|
|
+import message from "@/utils/message"
|
|
|
|
|
|
interface ExportImageConfig {
|
|
|
quality: number
|
|
@@ -28,7 +28,7 @@ export default () => {
|
|
|
return 96 * (viewportSize.value / 960)
|
|
|
})
|
|
|
const ratioPx2Pt = computed(() => {
|
|
|
- return 96 / 72 * (viewportSize.value / 960)
|
|
|
+ return (96 / 72) * (viewportSize.value / 960)
|
|
|
})
|
|
|
|
|
|
const exporting = ref(false)
|
|
@@ -36,35 +36,37 @@ export default () => {
|
|
|
// 导出图片
|
|
|
const exportImage = (domRef: HTMLElement, format: string, quality: number, ignoreWebfont = true) => {
|
|
|
exporting.value = true
|
|
|
- const toImage = format === 'png' ? toPng : toJpeg
|
|
|
+ const toImage = format === "png" ? toPng : toJpeg
|
|
|
|
|
|
- const foreignObjectSpans = domRef.querySelectorAll('foreignObject [xmlns]')
|
|
|
- foreignObjectSpans.forEach(spanRef => spanRef.removeAttribute('xmlns'))
|
|
|
+ const foreignObjectSpans = domRef.querySelectorAll("foreignObject [xmlns]")
|
|
|
+ foreignObjectSpans.forEach(spanRef => spanRef.removeAttribute("xmlns"))
|
|
|
|
|
|
setTimeout(() => {
|
|
|
const config: ExportImageConfig = {
|
|
|
quality,
|
|
|
- width: 1600,
|
|
|
+ width: 1600
|
|
|
}
|
|
|
|
|
|
- if (ignoreWebfont) config.fontEmbedCSS = ''
|
|
|
-
|
|
|
- toImage(domRef, config).then(dataUrl => {
|
|
|
- exporting.value = false
|
|
|
- saveAs(dataUrl, `${title.value}.${format}`)
|
|
|
- }).catch(() => {
|
|
|
- exporting.value = false
|
|
|
- message.error('导出图片失败')
|
|
|
- })
|
|
|
+ if (ignoreWebfont) config.fontEmbedCSS = ""
|
|
|
+
|
|
|
+ toImage(domRef, config)
|
|
|
+ .then(dataUrl => {
|
|
|
+ exporting.value = false
|
|
|
+ saveAs(dataUrl, `${title.value}.${format}`)
|
|
|
+ })
|
|
|
+ .catch(() => {
|
|
|
+ exporting.value = false
|
|
|
+ message.error("导出图片失败")
|
|
|
+ })
|
|
|
}, 200)
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 导出pptist文件(特有 .pptist 后缀文件)
|
|
|
const exportSpecificFile = (_slides: Slide[]) => {
|
|
|
- const blob = new Blob([encrypt(JSON.stringify(_slides))], { type: '' })
|
|
|
+ const blob = new Blob([encrypt(JSON.stringify(_slides))], { type: "" })
|
|
|
saveAs(blob, `${title.value}.pptist`)
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 导出JSON文件
|
|
|
const exportJSON = () => {
|
|
|
const json = {
|
|
@@ -72,8 +74,9 @@ export default () => {
|
|
|
width: viewportSize.value,
|
|
|
height: viewportSize.value * viewportRatio.value,
|
|
|
slides: slides.value,
|
|
|
+ theme: theme.value
|
|
|
}
|
|
|
- const blob = new Blob([JSON.stringify(json)], { type: '' })
|
|
|
+ const blob = new Blob([JSON.stringify(json)], { type: "" })
|
|
|
saveAs(blob, `${title.value}.json`)
|
|
|
}
|
|
|
|
|
@@ -81,10 +84,10 @@ export default () => {
|
|
|
const formatColor = (_color: string) => {
|
|
|
const c = tinycolor(_color)
|
|
|
const alpha = c.getAlpha()
|
|
|
- const color = alpha === 0 ? '#ffffff' : c.setAlpha(1).toHexString()
|
|
|
+ const color = alpha === 0 ? "#ffffff" : c.setAlpha(1).toHexString()
|
|
|
return {
|
|
|
alpha,
|
|
|
- color,
|
|
|
+ color
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -99,9 +102,8 @@ export default () => {
|
|
|
|
|
|
const slices: pptxgen.TextProps[] = []
|
|
|
const parse = (obj: AST[], baseStyleObj: { [key: string]: string } = {}) => {
|
|
|
-
|
|
|
for (const item of obj) {
|
|
|
- const isBlockTag = 'tagName' in item && ['div', 'li', 'p'].includes(item.tagName)
|
|
|
+ const isBlockTag = "tagName" in item && ["div", "li", "p"].includes(item.tagName)
|
|
|
|
|
|
if (isBlockTag && slices.length) {
|
|
|
const lastSlice = slices[slices.length - 1]
|
|
@@ -110,104 +112,108 @@ export default () => {
|
|
|
}
|
|
|
|
|
|
const styleObj = { ...baseStyleObj }
|
|
|
- const styleAttr = 'attributes' in item ? item.attributes.find(attr => attr.key === 'style') : null
|
|
|
+ const styleAttr = "attributes" in item ? item.attributes.find(attr => attr.key === "style") : null
|
|
|
if (styleAttr && styleAttr.value) {
|
|
|
- const styleArr = styleAttr.value.split(';')
|
|
|
+ const styleArr = styleAttr.value.split(";")
|
|
|
for (const styleItem of styleArr) {
|
|
|
- const [_key, _value] = styleItem.split(': ')
|
|
|
+ const [_key, _value] = styleItem.split(": ")
|
|
|
const [key, value] = [trim(_key), trim(_value)]
|
|
|
if (key && value) styleObj[key] = value
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if ('tagName' in item) {
|
|
|
- if (item.tagName === 'em') {
|
|
|
- styleObj['font-style'] = 'italic'
|
|
|
+ if ("tagName" in item) {
|
|
|
+ if (item.tagName === "em") {
|
|
|
+ styleObj["font-style"] = "italic"
|
|
|
}
|
|
|
- if (item.tagName === 'strong') {
|
|
|
- styleObj['font-weight'] = 'bold'
|
|
|
+ if (item.tagName === "strong") {
|
|
|
+ styleObj["font-weight"] = "bold"
|
|
|
}
|
|
|
- if (item.tagName === 'sup') {
|
|
|
- styleObj['vertical-align'] = 'super'
|
|
|
+ if (item.tagName === "sup") {
|
|
|
+ styleObj["vertical-align"] = "super"
|
|
|
}
|
|
|
- if (item.tagName === 'sub') {
|
|
|
- styleObj['vertical-align'] = 'sub'
|
|
|
+ if (item.tagName === "sub") {
|
|
|
+ styleObj["vertical-align"] = "sub"
|
|
|
}
|
|
|
- if (item.tagName === 'a') {
|
|
|
- const attr = item.attributes.find(attr => attr.key === 'href')
|
|
|
- styleObj['href'] = attr?.value || ''
|
|
|
+ if (item.tagName === "a") {
|
|
|
+ const attr = item.attributes.find(attr => attr.key === "href")
|
|
|
+ styleObj["href"] = attr?.value || ""
|
|
|
}
|
|
|
- if (item.tagName === 'ul') {
|
|
|
- styleObj['list-type'] = 'ul'
|
|
|
+ if (item.tagName === "ul") {
|
|
|
+ styleObj["list-type"] = "ul"
|
|
|
}
|
|
|
- if (item.tagName === 'ol') {
|
|
|
- styleObj['list-type'] = 'ol'
|
|
|
+ if (item.tagName === "ol") {
|
|
|
+ styleObj["list-type"] = "ol"
|
|
|
}
|
|
|
- if (item.tagName === 'li') {
|
|
|
+ if (item.tagName === "li") {
|
|
|
bulletFlag = true
|
|
|
}
|
|
|
- if (item.tagName === 'p') {
|
|
|
- if ('attributes' in item) {
|
|
|
- const dataIndentAttr = item.attributes.find(attr => attr.key === 'data-indent')
|
|
|
+ if (item.tagName === "p") {
|
|
|
+ if ("attributes" in item) {
|
|
|
+ const dataIndentAttr = item.attributes.find(attr => attr.key === "data-indent")
|
|
|
if (dataIndentAttr && dataIndentAttr.value) indent = +dataIndentAttr.value
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if ('tagName' in item && item.tagName === 'br') {
|
|
|
- slices.push({ text: '', options: { breakLine: true } })
|
|
|
- }
|
|
|
- else if ('content' in item) {
|
|
|
- const text = item.content.replace(/ /g, ' ').replace(/>/g, '>').replace(/</g, '<').replace(/&/g, '&').replace(/\n/g, '')
|
|
|
+ if ("tagName" in item && item.tagName === "br") {
|
|
|
+ slices.push({ text: "", options: { breakLine: true } })
|
|
|
+ } else if ("content" in item) {
|
|
|
+ const text = item.content
|
|
|
+ .replace(/ /g, " ")
|
|
|
+ .replace(/>/g, ">")
|
|
|
+ .replace(/</g, "<")
|
|
|
+ .replace(/&/g, "&")
|
|
|
+ .replace(/\n/g, "")
|
|
|
const options: pptxgen.TextPropsOptions = {}
|
|
|
|
|
|
- if (styleObj['font-size']) {
|
|
|
- options.fontSize = parseInt(styleObj['font-size']) / ratioPx2Pt.value
|
|
|
+ if (styleObj["font-size"]) {
|
|
|
+ options.fontSize = parseInt(styleObj["font-size"]) / ratioPx2Pt.value
|
|
|
}
|
|
|
- if (styleObj['color']) {
|
|
|
- options.color = formatColor(styleObj['color']).color
|
|
|
+ if (styleObj["color"]) {
|
|
|
+ options.color = formatColor(styleObj["color"]).color
|
|
|
}
|
|
|
- if (styleObj['background-color']) {
|
|
|
- options.highlight = formatColor(styleObj['background-color']).color
|
|
|
+ if (styleObj["background-color"]) {
|
|
|
+ options.highlight = formatColor(styleObj["background-color"]).color
|
|
|
}
|
|
|
- if (styleObj['text-decoration-line']) {
|
|
|
- if (styleObj['text-decoration-line'].indexOf('underline') !== -1) {
|
|
|
+ if (styleObj["text-decoration-line"]) {
|
|
|
+ if (styleObj["text-decoration-line"].indexOf("underline") !== -1) {
|
|
|
options.underline = {
|
|
|
- color: options.color || '#000000',
|
|
|
- style: 'sng',
|
|
|
+ color: options.color || "#000000",
|
|
|
+ style: "sng"
|
|
|
}
|
|
|
}
|
|
|
- if (styleObj['text-decoration-line'].indexOf('line-through') !== -1) {
|
|
|
- options.strike = 'sngStrike'
|
|
|
+ if (styleObj["text-decoration-line"].indexOf("line-through") !== -1) {
|
|
|
+ options.strike = "sngStrike"
|
|
|
}
|
|
|
}
|
|
|
- if (styleObj['text-decoration']) {
|
|
|
- if (styleObj['text-decoration'].indexOf('underline') !== -1) {
|
|
|
+ if (styleObj["text-decoration"]) {
|
|
|
+ if (styleObj["text-decoration"].indexOf("underline") !== -1) {
|
|
|
options.underline = {
|
|
|
- color: options.color || '#000000',
|
|
|
- style: 'sng',
|
|
|
+ color: options.color || "#000000",
|
|
|
+ style: "sng"
|
|
|
}
|
|
|
}
|
|
|
- if (styleObj['text-decoration'].indexOf('line-through') !== -1) {
|
|
|
- options.strike = 'sngStrike'
|
|
|
+ if (styleObj["text-decoration"].indexOf("line-through") !== -1) {
|
|
|
+ options.strike = "sngStrike"
|
|
|
}
|
|
|
}
|
|
|
- if (styleObj['vertical-align']) {
|
|
|
- if (styleObj['vertical-align'] === 'super') options.superscript = true
|
|
|
- if (styleObj['vertical-align'] === 'sub') options.subscript = true
|
|
|
+ if (styleObj["vertical-align"]) {
|
|
|
+ if (styleObj["vertical-align"] === "super") options.superscript = true
|
|
|
+ if (styleObj["vertical-align"] === "sub") options.subscript = true
|
|
|
}
|
|
|
- if (styleObj['text-align']) options.align = styleObj['text-align'] as pptxgen.HAlign
|
|
|
- if (styleObj['font-weight']) options.bold = styleObj['font-weight'] === 'bold'
|
|
|
- if (styleObj['font-style']) options.italic = styleObj['font-style'] === 'italic'
|
|
|
- if (styleObj['font-family']) options.fontFace = styleObj['font-family']
|
|
|
- if (styleObj['href']) options.hyperlink = { url: styleObj['href'] }
|
|
|
+ if (styleObj["text-align"]) options.align = styleObj["text-align"] as pptxgen.HAlign
|
|
|
+ if (styleObj["font-weight"]) options.bold = styleObj["font-weight"] === "bold"
|
|
|
+ if (styleObj["font-style"]) options.italic = styleObj["font-style"] === "italic"
|
|
|
+ if (styleObj["font-family"]) options.fontFace = styleObj["font-family"]
|
|
|
+ if (styleObj["href"]) options.hyperlink = { url: styleObj["href"] }
|
|
|
|
|
|
- if (bulletFlag && styleObj['list-type'] === 'ol') {
|
|
|
- options.bullet = { type: 'number', indent: (options.fontSize || 20) * 1.25 }
|
|
|
+ if (bulletFlag && styleObj["list-type"] === "ol") {
|
|
|
+ options.bullet = { type: "number", indent: (options.fontSize || 20) * 1.25 }
|
|
|
options.paraSpaceBefore = 0.1
|
|
|
bulletFlag = false
|
|
|
}
|
|
|
- if (bulletFlag && styleObj['list-type'] === 'ul') {
|
|
|
+ if (bulletFlag && styleObj["list-type"] === "ul") {
|
|
|
options.bullet = { indent: (options.fontSize || 20) * 1.25 }
|
|
|
options.paraSpaceBefore = 0.1
|
|
|
bulletFlag = false
|
|
@@ -218,8 +224,7 @@ export default () => {
|
|
|
}
|
|
|
|
|
|
slices.push({ text, options })
|
|
|
- }
|
|
|
- else if ('children' in item) parse(item.children, styleObj)
|
|
|
+ } else if ("children" in item) parse(item.children, styleObj)
|
|
|
}
|
|
|
}
|
|
|
parse(ast)
|
|
@@ -228,9 +233,9 @@ export default () => {
|
|
|
|
|
|
type Points = Array<
|
|
|
| { x: number; y: number; moveTo?: boolean }
|
|
|
- | { x: number; y: number; curve: { type: 'arc'; hR: number; wR: number; stAng: number; swAng: number } }
|
|
|
- | { x: number; y: number; curve: { type: 'quadratic'; x1: number; y1: number } }
|
|
|
- | { x: number; y: number; curve: { type: 'cubic'; x1: number; y1: number; x2: number; y2: number } }
|
|
|
+ | { x: number; y: number; curve: { type: "arc"; hR: number; wR: number; stAng: number; swAng: number } }
|
|
|
+ | { x: number; y: number; curve: { type: "quadratic"; x1: number; y1: number } }
|
|
|
+ | { x: number; y: number; curve: { type: "cubic"; x1: number; y1: number; x2: number; y2: number } }
|
|
|
| { close: true }
|
|
|
>
|
|
|
|
|
@@ -239,43 +244,40 @@ export default () => {
|
|
|
return points.map(point => {
|
|
|
if (point.close !== undefined) {
|
|
|
return { close: true }
|
|
|
- }
|
|
|
- else if (point.type === 'M') {
|
|
|
+ } else if (point.type === "M") {
|
|
|
return {
|
|
|
- x: point.x / ratioPx2Inch.value * scale.x,
|
|
|
- y: point.y / ratioPx2Inch.value * scale.y,
|
|
|
- moveTo: true,
|
|
|
+ x: (point.x / ratioPx2Inch.value) * scale.x,
|
|
|
+ y: (point.y / ratioPx2Inch.value) * scale.y,
|
|
|
+ moveTo: true
|
|
|
}
|
|
|
- }
|
|
|
- else if (point.curve) {
|
|
|
- if (point.curve.type === 'cubic') {
|
|
|
+ } else if (point.curve) {
|
|
|
+ if (point.curve.type === "cubic") {
|
|
|
return {
|
|
|
- x: point.x / ratioPx2Inch.value * scale.x,
|
|
|
- y: point.y / ratioPx2Inch.value * scale.y,
|
|
|
+ x: (point.x / ratioPx2Inch.value) * scale.x,
|
|
|
+ y: (point.y / ratioPx2Inch.value) * scale.y,
|
|
|
curve: {
|
|
|
- type: 'cubic',
|
|
|
- x1: (point.curve.x1 as number) / ratioPx2Inch.value * scale.x,
|
|
|
- y1: (point.curve.y1 as number) / ratioPx2Inch.value * scale.y,
|
|
|
- x2: (point.curve.x2 as number) / ratioPx2Inch.value * scale.x,
|
|
|
- y2: (point.curve.y2 as number) / ratioPx2Inch.value * scale.y,
|
|
|
- },
|
|
|
+ type: "cubic",
|
|
|
+ x1: ((point.curve.x1 as number) / ratioPx2Inch.value) * scale.x,
|
|
|
+ y1: ((point.curve.y1 as number) / ratioPx2Inch.value) * scale.y,
|
|
|
+ x2: ((point.curve.x2 as number) / ratioPx2Inch.value) * scale.x,
|
|
|
+ y2: ((point.curve.y2 as number) / ratioPx2Inch.value) * scale.y
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
- else if (point.curve.type === 'quadratic') {
|
|
|
+ } else if (point.curve.type === "quadratic") {
|
|
|
return {
|
|
|
- x: point.x / ratioPx2Inch.value * scale.x,
|
|
|
- y: point.y / ratioPx2Inch.value * scale.y,
|
|
|
+ x: (point.x / ratioPx2Inch.value) * scale.x,
|
|
|
+ y: (point.y / ratioPx2Inch.value) * scale.y,
|
|
|
curve: {
|
|
|
- type: 'quadratic',
|
|
|
- x1: (point.curve.x1 as number) / ratioPx2Inch.value * scale.x,
|
|
|
- y1: (point.curve.y1 as number) / ratioPx2Inch.value * scale.y,
|
|
|
- },
|
|
|
+ type: "quadratic",
|
|
|
+ x1: ((point.curve.x1 as number) / ratioPx2Inch.value) * scale.x,
|
|
|
+ y1: ((point.curve.y1 as number) / ratioPx2Inch.value) * scale.y
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
return {
|
|
|
- x: point.x / ratioPx2Inch.value * scale.x,
|
|
|
- y: point.y / ratioPx2Inch.value * scale.y,
|
|
|
+ x: (point.x / ratioPx2Inch.value) * scale.x,
|
|
|
+ y: (point.y / ratioPx2Inch.value) * scale.y
|
|
|
}
|
|
|
})
|
|
|
}
|
|
@@ -291,77 +293,69 @@ export default () => {
|
|
|
if (h === 0 && v === 0) {
|
|
|
offset = 4
|
|
|
angle = 45
|
|
|
- }
|
|
|
- else if (h === 0) {
|
|
|
+ } else if (h === 0) {
|
|
|
if (v > 0) {
|
|
|
offset = v
|
|
|
angle = 90
|
|
|
- }
|
|
|
- else {
|
|
|
+ } else {
|
|
|
offset = -v
|
|
|
angle = 270
|
|
|
}
|
|
|
- }
|
|
|
- else if (v === 0) {
|
|
|
+ } else if (v === 0) {
|
|
|
if (h > 0) {
|
|
|
offset = h
|
|
|
angle = 1
|
|
|
- }
|
|
|
- else {
|
|
|
+ } else {
|
|
|
offset = -h
|
|
|
angle = 180
|
|
|
}
|
|
|
- }
|
|
|
- else if (h > 0 && v > 0) {
|
|
|
+ } else if (h > 0 && v > 0) {
|
|
|
offset = Math.max(h, v)
|
|
|
angle = 45
|
|
|
- }
|
|
|
- else if (h > 0 && v < 0) {
|
|
|
+ } else if (h > 0 && v < 0) {
|
|
|
offset = Math.max(h, -v)
|
|
|
angle = 315
|
|
|
- }
|
|
|
- else if (h < 0 && v > 0) {
|
|
|
+ } else if (h < 0 && v > 0) {
|
|
|
offset = Math.max(-h, v)
|
|
|
angle = 135
|
|
|
- }
|
|
|
- else if (h < 0 && v < 0) {
|
|
|
+ } else if (h < 0 && v < 0) {
|
|
|
offset = Math.max(-h, -v)
|
|
|
angle = 225
|
|
|
}
|
|
|
|
|
|
return {
|
|
|
- type: 'outer',
|
|
|
- color: c.color.replace('#', ''),
|
|
|
+ type: "outer",
|
|
|
+ color: c.color.replace("#", ""),
|
|
|
opacity: c.alpha,
|
|
|
blur: shadow.blur / ratioPx2Pt.value,
|
|
|
offset,
|
|
|
- angle,
|
|
|
+ angle
|
|
|
}
|
|
|
}
|
|
|
|
|
|
const dashTypeMap = {
|
|
|
- 'solid': 'solid',
|
|
|
- 'dashed': 'dash',
|
|
|
- 'dotted': 'sysDot',
|
|
|
+ solid: "solid",
|
|
|
+ dashed: "dash",
|
|
|
+ dotted: "sysDot"
|
|
|
}
|
|
|
|
|
|
// 获取边框配置
|
|
|
const getOutlineOption = (outline: PPTElementOutline): pptxgen.ShapeLineProps => {
|
|
|
- const c = formatColor(outline?.color || '#000000')
|
|
|
-
|
|
|
+ const c = formatColor(outline?.color || "#000000")
|
|
|
+
|
|
|
return {
|
|
|
- color: c.color,
|
|
|
+ color: c.color,
|
|
|
transparency: (1 - c.alpha) * 100,
|
|
|
- width: (outline.width || 1) / ratioPx2Pt.value,
|
|
|
- dashType: outline.style ? dashTypeMap[outline.style] as 'solid' | 'dash' | 'sysDot' : 'solid',
|
|
|
+ width: (outline.width || 1) / ratioPx2Pt.value,
|
|
|
+ dashType: outline.style ? (dashTypeMap[outline.style] as "solid" | "dash" | "sysDot") : "solid"
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 获取超链接配置
|
|
|
const getLinkOption = (link: PPTElementLink): pptxgen.HyperlinkProps | null => {
|
|
|
const { type, target } = link
|
|
|
- if (type === 'web') return { url: target }
|
|
|
- if (type === 'slide') {
|
|
|
+ if (type === "web") return { url: target }
|
|
|
+ if (type === "slide") {
|
|
|
const index = slides.value.findIndex(slide => slide.id === target)
|
|
|
if (index !== -1) return { slide: index + 1 }
|
|
|
}
|
|
@@ -380,23 +374,21 @@ export default () => {
|
|
|
exporting.value = true
|
|
|
const pptx = new pptxgen()
|
|
|
|
|
|
- if (viewportRatio.value === 0.625) pptx.layout = 'LAYOUT_16x10'
|
|
|
- else if (viewportRatio.value === 0.75) pptx.layout = 'LAYOUT_4x3'
|
|
|
+ if (viewportRatio.value === 0.625) pptx.layout = "LAYOUT_16x10"
|
|
|
+ else if (viewportRatio.value === 0.75) pptx.layout = "LAYOUT_4x3"
|
|
|
else if (viewportRatio.value === 0.70710678) {
|
|
|
- pptx.defineLayout({ name: 'A3', width: 10, height: 7.0710678 })
|
|
|
- pptx.layout = 'A3'
|
|
|
- }
|
|
|
- else if (viewportRatio.value === 1.41421356) {
|
|
|
- pptx.defineLayout({ name: 'A3_V', width: 10, height: 14.1421356 })
|
|
|
- pptx.layout = 'A3_V'
|
|
|
- }
|
|
|
- else pptx.layout = 'LAYOUT_16x9'
|
|
|
+ pptx.defineLayout({ name: "A3", width: 10, height: 7.0710678 })
|
|
|
+ pptx.layout = "A3"
|
|
|
+ } else if (viewportRatio.value === 1.41421356) {
|
|
|
+ pptx.defineLayout({ name: "A3_V", width: 10, height: 14.1421356 })
|
|
|
+ pptx.layout = "A3_V"
|
|
|
+ } else pptx.layout = "LAYOUT_16x9"
|
|
|
|
|
|
if (masterOverwrite) {
|
|
|
const { color: bgColor, alpha: bgAlpha } = formatColor(theme.value.backgroundColor)
|
|
|
pptx.defineSlideMaster({
|
|
|
- title: 'PPTIST_MASTER',
|
|
|
- background: { color: bgColor, transparency: (1 - bgAlpha) * 100 },
|
|
|
+ title: "PPTIST_MASTER",
|
|
|
+ background: { color: bgColor, transparency: (1 - bgAlpha) * 100 }
|
|
|
})
|
|
|
}
|
|
|
|
|
@@ -405,15 +397,13 @@ export default () => {
|
|
|
|
|
|
if (slide.background) {
|
|
|
const background = slide.background
|
|
|
- if (background.type === 'image' && background.image) {
|
|
|
+ if (background.type === "image" && background.image) {
|
|
|
if (isBase64Image(background.image.src)) pptxSlide.background = { data: background.image.src }
|
|
|
else pptxSlide.background = { path: background.image.src }
|
|
|
- }
|
|
|
- else if (background.type === 'solid' && background.color) {
|
|
|
+ } else if (background.type === "solid" && background.color) {
|
|
|
const c = formatColor(background.color)
|
|
|
pptxSlide.background = { color: c.color, transparency: (1 - c.alpha) * 100 }
|
|
|
- }
|
|
|
- else if (background.type === 'gradient' && background.gradient) {
|
|
|
+ } else if (background.type === "gradient" && background.gradient) {
|
|
|
const colors = background.gradient.colors
|
|
|
const color1 = colors[0].color
|
|
|
const color2 = colors[colors.length - 1].color
|
|
@@ -427,7 +417,7 @@ export default () => {
|
|
|
if (!slide.elements) continue
|
|
|
|
|
|
for (const el of slide.elements) {
|
|
|
- if (el.type === 'text') {
|
|
|
+ if (el.type === "text") {
|
|
|
const textProps = formatHTML(el.content)
|
|
|
|
|
|
const options: pptxgen.TextPropsOptions = {
|
|
@@ -436,13 +426,13 @@ export default () => {
|
|
|
w: el.width / ratioPx2Inch.value,
|
|
|
h: el.height / ratioPx2Inch.value,
|
|
|
fontSize: 20 / ratioPx2Pt.value,
|
|
|
- fontFace: '微软雅黑',
|
|
|
- color: '#000000',
|
|
|
- valign: 'top',
|
|
|
+ fontFace: "微软雅黑",
|
|
|
+ color: "#000000",
|
|
|
+ valign: "top",
|
|
|
margin: 10 / ratioPx2Pt.value,
|
|
|
paraSpaceBefore: 5 / ratioPx2Pt.value,
|
|
|
lineSpacingMultiple: 1.5 / 1.25,
|
|
|
- autoFit: true,
|
|
|
+ autoFit: true
|
|
|
}
|
|
|
if (el.rotate) options.rotate = el.rotate
|
|
|
if (el.wordSpace) options.charSpacing = el.wordSpace / ratioPx2Pt.value
|
|
@@ -458,17 +448,15 @@ export default () => {
|
|
|
if (el.outline?.width) options.line = getOutlineOption(el.outline)
|
|
|
if (el.opacity !== undefined) options.transparency = (1 - el.opacity) * 100
|
|
|
if (el.paragraphSpace !== undefined) options.paraSpaceBefore = el.paragraphSpace / ratioPx2Pt.value
|
|
|
- if (el.vertical) options.vert = 'eaVert'
|
|
|
+ if (el.vertical) options.vert = "eaVert"
|
|
|
|
|
|
pptxSlide.addText(textProps, options)
|
|
|
- }
|
|
|
-
|
|
|
- else if (el.type === 'image') {
|
|
|
+ } else if (el.type === "image") {
|
|
|
const options: pptxgen.ImageProps = {
|
|
|
x: el.left / ratioPx2Inch.value,
|
|
|
y: el.top / ratioPx2Inch.value,
|
|
|
w: el.width / ratioPx2Inch.value,
|
|
|
- h: el.height / ratioPx2Inch.value,
|
|
|
+ h: el.height / ratioPx2Inch.value
|
|
|
}
|
|
|
if (isBase64Image(el.src)) options.data = el.src
|
|
|
else options.path = el.src
|
|
@@ -482,7 +470,7 @@ export default () => {
|
|
|
}
|
|
|
if (el.filters?.opacity) options.transparency = 100 - parseInt(el.filters?.opacity)
|
|
|
if (el.clip) {
|
|
|
- if (el.clip.shape === 'ellipse') options.rounding = true
|
|
|
+ if (el.clip.shape === "ellipse") options.rounding = true
|
|
|
|
|
|
const [start, end] = el.clip.range
|
|
|
const [startX, startY] = start
|
|
@@ -495,18 +483,16 @@ export default () => {
|
|
|
options.h = originH / ratioPx2Inch.value
|
|
|
|
|
|
options.sizing = {
|
|
|
- type: 'crop',
|
|
|
- x: startX / ratioPx2Inch.value * originW / ratioPx2Inch.value,
|
|
|
- y: startY / ratioPx2Inch.value * originH / ratioPx2Inch.value,
|
|
|
- w: (endX - startX) / ratioPx2Inch.value * originW / ratioPx2Inch.value,
|
|
|
- h: (endY - startY) / ratioPx2Inch.value * originH / ratioPx2Inch.value,
|
|
|
+ type: "crop",
|
|
|
+ x: ((startX / ratioPx2Inch.value) * originW) / ratioPx2Inch.value,
|
|
|
+ y: ((startY / ratioPx2Inch.value) * originH) / ratioPx2Inch.value,
|
|
|
+ w: (((endX - startX) / ratioPx2Inch.value) * originW) / ratioPx2Inch.value,
|
|
|
+ h: (((endY - startY) / ratioPx2Inch.value) * originH) / ratioPx2Inch.value
|
|
|
}
|
|
|
}
|
|
|
|
|
|
pptxSlide.addImage(options)
|
|
|
- }
|
|
|
-
|
|
|
- else if (el.type === 'shape') {
|
|
|
+ } else if (el.type === "shape") {
|
|
|
if (el.special) {
|
|
|
const svgRef = document.querySelector(`.thumbnail-list .base-element-${el.id} svg`) as HTMLElement
|
|
|
if (svgRef.clientWidth < 1 || svgRef.clientHeight < 1) continue // 临时处理(导入PPTX文件带来的异常数据)
|
|
@@ -517,7 +503,7 @@ export default () => {
|
|
|
x: el.left / ratioPx2Inch.value,
|
|
|
y: el.top / ratioPx2Inch.value,
|
|
|
w: el.width / ratioPx2Inch.value,
|
|
|
- h: el.height / ratioPx2Inch.value,
|
|
|
+ h: el.height / ratioPx2Inch.value
|
|
|
}
|
|
|
if (el.rotate) options.rotate = el.rotate
|
|
|
if (el.link) {
|
|
@@ -526,14 +512,13 @@ export default () => {
|
|
|
}
|
|
|
|
|
|
pptxSlide.addImage(options)
|
|
|
- }
|
|
|
- else {
|
|
|
+ } else {
|
|
|
const scale = {
|
|
|
x: el.width / el.viewBox[0],
|
|
|
- y: el.height / el.viewBox[1],
|
|
|
+ y: el.height / el.viewBox[1]
|
|
|
}
|
|
|
const points = formatPoints(toPoints(el.path), scale)
|
|
|
-
|
|
|
+
|
|
|
let fillColor = formatColor(el.fill)
|
|
|
if (el.gradient) {
|
|
|
const colors = el.gradient.colors
|
|
@@ -543,14 +528,14 @@ export default () => {
|
|
|
fillColor = formatColor(color)
|
|
|
}
|
|
|
const opacity = el.opacity === undefined ? 1 : el.opacity
|
|
|
-
|
|
|
+
|
|
|
const options: pptxgen.ShapeProps = {
|
|
|
x: el.left / ratioPx2Inch.value,
|
|
|
y: el.top / ratioPx2Inch.value,
|
|
|
w: el.width / ratioPx2Inch.value,
|
|
|
h: el.height / ratioPx2Inch.value,
|
|
|
fill: { color: fillColor.color, transparency: (1 - fillColor.alpha * opacity) * 100 },
|
|
|
- points,
|
|
|
+ points
|
|
|
}
|
|
|
if (el.flipH) options.flipH = el.flipH
|
|
|
if (el.flipV) options.flipV = el.flipV
|
|
@@ -562,7 +547,7 @@ export default () => {
|
|
|
if (linkOption) options.hyperlink = linkOption
|
|
|
}
|
|
|
|
|
|
- pptxSlide.addShape('custGeom' as pptxgen.ShapeType, options)
|
|
|
+ pptxSlide.addShape("custGeom" as pptxgen.ShapeType, options)
|
|
|
}
|
|
|
if (el.text) {
|
|
|
const textProps = formatHTML(el.text.content)
|
|
@@ -573,10 +558,10 @@ export default () => {
|
|
|
w: el.width / ratioPx2Inch.value,
|
|
|
h: el.height / ratioPx2Inch.value,
|
|
|
fontSize: 20 / ratioPx2Pt.value,
|
|
|
- fontFace: '微软雅黑',
|
|
|
- color: '#000000',
|
|
|
+ fontFace: "微软雅黑",
|
|
|
+ color: "#000000",
|
|
|
paraSpaceBefore: 5 / ratioPx2Pt.value,
|
|
|
- valign: el.text.align,
|
|
|
+ valign: el.text.align
|
|
|
}
|
|
|
if (el.rotate) options.rotate = el.rotate
|
|
|
if (el.text.defaultColor) options.color = formatColor(el.text.defaultColor).color
|
|
@@ -584,9 +569,7 @@ export default () => {
|
|
|
|
|
|
pptxSlide.addText(textProps, options)
|
|
|
}
|
|
|
- }
|
|
|
-
|
|
|
- else if (el.type === 'line') {
|
|
|
+ } else if (el.type === "line") {
|
|
|
const path = getLineElementPath(el)
|
|
|
const points = formatPoints(toPoints(path))
|
|
|
const { minX, maxX, minY, maxY } = getElementRange(el)
|
|
@@ -598,56 +581,59 @@ export default () => {
|
|
|
w: (maxX - minX) / ratioPx2Inch.value,
|
|
|
h: (maxY - minY) / ratioPx2Inch.value,
|
|
|
line: {
|
|
|
- color: c.color,
|
|
|
+ color: c.color,
|
|
|
transparency: (1 - c.alpha) * 100,
|
|
|
- width: el.width / ratioPx2Pt.value,
|
|
|
- dashType: dashTypeMap[el.style] as 'solid' | 'dash' | 'sysDot',
|
|
|
- beginArrowType: el.points[0] ? 'arrow' : 'none',
|
|
|
- endArrowType: el.points[1] ? 'arrow' : 'none',
|
|
|
+ width: el.width / ratioPx2Pt.value,
|
|
|
+ dashType: dashTypeMap[el.style] as "solid" | "dash" | "sysDot",
|
|
|
+ beginArrowType: el.points[0] ? "arrow" : "none",
|
|
|
+ endArrowType: el.points[1] ? "arrow" : "none"
|
|
|
},
|
|
|
- points,
|
|
|
+ points
|
|
|
}
|
|
|
if (el.shadow) options.shadow = getShadowOption(el.shadow)
|
|
|
|
|
|
- pptxSlide.addShape('custGeom' as pptxgen.ShapeType, options)
|
|
|
- }
|
|
|
-
|
|
|
- else if (el.type === 'chart') {
|
|
|
+ pptxSlide.addShape("custGeom" as pptxgen.ShapeType, options)
|
|
|
+ } else if (el.type === "chart") {
|
|
|
const chartData = []
|
|
|
for (let i = 0; i < el.data.series.length; i++) {
|
|
|
const item = el.data.series[i]
|
|
|
chartData.push({
|
|
|
name: `系列${i + 1}`,
|
|
|
labels: el.data.labels,
|
|
|
- values: item,
|
|
|
+ values: item
|
|
|
})
|
|
|
}
|
|
|
|
|
|
let chartColors: string[] = []
|
|
|
if (el.themeColors.length === 10) chartColors = el.themeColors.map(color => formatColor(color).color)
|
|
|
- else if (el.themeColors.length === 1) chartColors = tinycolor(el.themeColors[0]).analogous(10).map(color => formatColor(color.toHexString()).color)
|
|
|
+ else if (el.themeColors.length === 1)
|
|
|
+ chartColors = tinycolor(el.themeColors[0])
|
|
|
+ .analogous(10)
|
|
|
+ .map(color => formatColor(color.toHexString()).color)
|
|
|
else {
|
|
|
const len = el.themeColors.length
|
|
|
- const supplement = tinycolor(el.themeColors[len - 1]).analogous(10 + 1 - len).map(color => color.toHexString())
|
|
|
+ const supplement = tinycolor(el.themeColors[len - 1])
|
|
|
+ .analogous(10 + 1 - len)
|
|
|
+ .map(color => color.toHexString())
|
|
|
chartColors = [...el.themeColors.slice(0, len - 1), ...supplement].map(color => formatColor(color).color)
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
const options: pptxgen.IChartOpts = {
|
|
|
x: el.left / ratioPx2Inch.value,
|
|
|
y: el.top / ratioPx2Inch.value,
|
|
|
w: el.width / ratioPx2Inch.value,
|
|
|
h: el.height / ratioPx2Inch.value,
|
|
|
- chartColors: (el.chartType === 'pie' || el.chartType === 'ring') ? chartColors : chartColors.slice(0, el.data.series.length),
|
|
|
+ chartColors: el.chartType === "pie" || el.chartType === "ring" ? chartColors : chartColors.slice(0, el.data.series.length)
|
|
|
}
|
|
|
|
|
|
- const textColor = formatColor(el.textColor || '#000000').color
|
|
|
+ const textColor = formatColor(el.textColor || "#000000").color
|
|
|
options.catAxisLabelColor = textColor
|
|
|
options.valAxisLabelColor = textColor
|
|
|
|
|
|
const fontSize = 14 / ratioPx2Pt.value
|
|
|
options.catAxisLabelFontSize = fontSize
|
|
|
options.valAxisLabelFontSize = fontSize
|
|
|
-
|
|
|
+
|
|
|
if (el.fill || el.outline) {
|
|
|
const plotArea: pptxgen.IChartPropsFillLine = {}
|
|
|
if (el.fill) {
|
|
@@ -656,56 +642,47 @@ export default () => {
|
|
|
if (el.outline) {
|
|
|
plotArea.border = {
|
|
|
pt: el.outline.width! / ratioPx2Pt.value,
|
|
|
- color: formatColor(el.outline.color!).color,
|
|
|
+ color: formatColor(el.outline.color!).color
|
|
|
}
|
|
|
}
|
|
|
options.plotArea = plotArea
|
|
|
}
|
|
|
|
|
|
- if ((el.data.series.length > 1 && el.chartType !== 'scatter') || el.chartType === 'pie' || el.chartType === 'ring') {
|
|
|
+ if ((el.data.series.length > 1 && el.chartType !== "scatter") || el.chartType === "pie" || el.chartType === "ring") {
|
|
|
options.showLegend = true
|
|
|
- options.legendPos = 'b'
|
|
|
+ options.legendPos = "b"
|
|
|
options.legendColor = textColor
|
|
|
options.legendFontSize = fontSize
|
|
|
}
|
|
|
|
|
|
let type = pptx.ChartType.bar
|
|
|
- if (el.chartType === 'bar') {
|
|
|
+ if (el.chartType === "bar") {
|
|
|
type = pptx.ChartType.bar
|
|
|
- options.barDir = 'col'
|
|
|
- if (el.options?.stack) options.barGrouping = 'stacked'
|
|
|
- }
|
|
|
- else if (el.chartType === 'column') {
|
|
|
+ options.barDir = "col"
|
|
|
+ if (el.options?.stack) options.barGrouping = "stacked"
|
|
|
+ } else if (el.chartType === "column") {
|
|
|
type = pptx.ChartType.bar
|
|
|
- options.barDir = 'bar'
|
|
|
- if (el.options?.stack) options.barGrouping = 'stacked'
|
|
|
- }
|
|
|
- else if (el.chartType === 'line') {
|
|
|
+ options.barDir = "bar"
|
|
|
+ if (el.options?.stack) options.barGrouping = "stacked"
|
|
|
+ } else if (el.chartType === "line") {
|
|
|
type = pptx.ChartType.line
|
|
|
if (el.options?.lineSmooth) options.lineSmooth = true
|
|
|
- }
|
|
|
- else if (el.chartType === 'area') {
|
|
|
+ } else if (el.chartType === "area") {
|
|
|
type = pptx.ChartType.area
|
|
|
- }
|
|
|
- else if (el.chartType === 'radar') {
|
|
|
+ } else if (el.chartType === "radar") {
|
|
|
type = pptx.ChartType.radar
|
|
|
- }
|
|
|
- else if (el.chartType === 'scatter') {
|
|
|
+ } else if (el.chartType === "scatter") {
|
|
|
type = pptx.ChartType.scatter
|
|
|
options.lineSize = 0
|
|
|
- }
|
|
|
- else if (el.chartType === 'pie') {
|
|
|
+ } else if (el.chartType === "pie") {
|
|
|
type = pptx.ChartType.pie
|
|
|
- }
|
|
|
- else if (el.chartType === 'ring') {
|
|
|
+ } else if (el.chartType === "ring") {
|
|
|
type = pptx.ChartType.doughnut
|
|
|
options.holeSize = 60
|
|
|
}
|
|
|
-
|
|
|
- pptxSlide.addChart(type, chartData, options)
|
|
|
- }
|
|
|
|
|
|
- else if (el.type === 'table') {
|
|
|
+ pptxSlide.addChart(type, chartData, options)
|
|
|
+ } else if (el.type === "table") {
|
|
|
const hiddenCells = []
|
|
|
for (let i = 0; i < el.data.length; i++) {
|
|
|
const rowData = el.data[i]
|
|
@@ -741,11 +718,11 @@ export default () => {
|
|
|
rowspan: cell.rowspan,
|
|
|
bold: cell.style?.bold || false,
|
|
|
italic: cell.style?.em || false,
|
|
|
- underline: { style: cell.style?.underline ? 'sng' : 'none' },
|
|
|
- align: cell.style?.align || 'left',
|
|
|
- valign: 'middle',
|
|
|
- fontFace: cell.style?.fontname || '微软雅黑',
|
|
|
- fontSize: (cell.style?.fontsize ? parseInt(cell.style?.fontsize) : 14) / ratioPx2Pt.value,
|
|
|
+ underline: { style: cell.style?.underline ? "sng" : "none" },
|
|
|
+ align: cell.style?.align || "left",
|
|
|
+ valign: "middle",
|
|
|
+ fontFace: cell.style?.fontname || "微软雅黑",
|
|
|
+ fontSize: (cell.style?.fontsize ? parseInt(cell.style?.fontsize) : 14) / ratioPx2Pt.value
|
|
|
}
|
|
|
if (theme && themeColor) {
|
|
|
let c: FormatColor
|
|
@@ -768,7 +745,7 @@ export default () => {
|
|
|
if (!hiddenCells.includes(`${i}_${j}`)) {
|
|
|
_row.push({
|
|
|
text: cell.text,
|
|
|
- options: cellOptions,
|
|
|
+ options: cellOptions
|
|
|
})
|
|
|
}
|
|
|
}
|
|
@@ -780,21 +757,19 @@ export default () => {
|
|
|
y: el.top / ratioPx2Inch.value,
|
|
|
w: el.width / ratioPx2Inch.value,
|
|
|
h: el.height / ratioPx2Inch.value,
|
|
|
- colW: el.colWidths.map(item => el.width * item / ratioPx2Inch.value),
|
|
|
+ colW: el.colWidths.map(item => (el.width * item) / ratioPx2Inch.value)
|
|
|
}
|
|
|
- if (el.theme) options.fill = { color: '#ffffff' }
|
|
|
+ if (el.theme) options.fill = { color: "#ffffff" }
|
|
|
if (el.outline.width && el.outline.color) {
|
|
|
options.border = {
|
|
|
- type: el.outline.style === 'solid' ? 'solid' : 'dash',
|
|
|
+ type: el.outline.style === "solid" ? "solid" : "dash",
|
|
|
pt: el.outline.width / ratioPx2Pt.value,
|
|
|
- color: formatColor(el.outline.color).color,
|
|
|
+ color: formatColor(el.outline.color).color
|
|
|
}
|
|
|
}
|
|
|
|
|
|
pptxSlide.addTable(tableData, options)
|
|
|
- }
|
|
|
-
|
|
|
- else if (el.type === 'latex') {
|
|
|
+ } else if (el.type === "latex") {
|
|
|
const svgRef = document.querySelector(`.thumbnail-list .base-element-${el.id} svg`) as HTMLElement
|
|
|
const base64SVG = svg2Base64(svgRef)
|
|
|
|
|
@@ -803,7 +778,7 @@ export default () => {
|
|
|
x: el.left / ratioPx2Inch.value,
|
|
|
y: el.top / ratioPx2Inch.value,
|
|
|
w: el.width / ratioPx2Inch.value,
|
|
|
- h: el.height / ratioPx2Inch.value,
|
|
|
+ h: el.height / ratioPx2Inch.value
|
|
|
}
|
|
|
if (el.link) {
|
|
|
const linkOption = getLinkOption(el.link)
|
|
@@ -811,25 +786,23 @@ export default () => {
|
|
|
}
|
|
|
|
|
|
pptxSlide.addImage(options)
|
|
|
- }
|
|
|
-
|
|
|
- else if (!ignoreMedia && (el.type === 'video' || el.type === 'audio')) {
|
|
|
+ } else if (!ignoreMedia && (el.type === "video" || el.type === "audio")) {
|
|
|
const options: pptxgen.MediaProps = {
|
|
|
x: el.left / ratioPx2Inch.value,
|
|
|
y: el.top / ratioPx2Inch.value,
|
|
|
w: el.width / ratioPx2Inch.value,
|
|
|
h: el.height / ratioPx2Inch.value,
|
|
|
path: el.src,
|
|
|
- type: el.type,
|
|
|
+ type: el.type
|
|
|
}
|
|
|
- if (el.type === 'video' && el.poster) options.cover = el.poster
|
|
|
+ if (el.type === "video" && el.poster) options.cover = el.poster
|
|
|
|
|
|
const extMatch = el.src.match(/\.([a-zA-Z0-9]+)(?:[\?#]|$)/)
|
|
|
if (extMatch && extMatch[1]) options.extn = extMatch[1]
|
|
|
else if (el.ext) options.extn = el.ext
|
|
|
-
|
|
|
- const videoExts = ['avi', 'mp4', 'm4v', 'mov', 'wmv']
|
|
|
- const audioExts = ['mp3', 'm4a', 'mp4', 'wav', 'wma']
|
|
|
+
|
|
|
+ const videoExts = ["avi", "mp4", "m4v", "mov", "wmv"]
|
|
|
+ const audioExts = ["mp3", "m4a", "mp4", "wav", "wma"]
|
|
|
if (options.extn && [...videoExts, ...audioExts].includes(options.extn)) {
|
|
|
pptxSlide.addMedia(options)
|
|
|
}
|
|
@@ -838,10 +811,13 @@ export default () => {
|
|
|
}
|
|
|
|
|
|
setTimeout(() => {
|
|
|
- pptx.writeFile({ fileName: `${title.value}.pptx` }).then(() => exporting.value = false).catch(() => {
|
|
|
- exporting.value = false
|
|
|
- message.error('导出失败')
|
|
|
- })
|
|
|
+ pptx
|
|
|
+ .writeFile({ fileName: `${title.value}.pptx` })
|
|
|
+ .then(() => (exporting.value = false))
|
|
|
+ .catch(() => {
|
|
|
+ exporting.value = false
|
|
|
+ message.error("导出失败")
|
|
|
+ })
|
|
|
}, 200)
|
|
|
}
|
|
|
|
|
@@ -850,6 +826,6 @@ export default () => {
|
|
|
exportImage,
|
|
|
exportJSON,
|
|
|
exportSpecificFile,
|
|
|
- exportPPTX,
|
|
|
+ exportPPTX
|
|
|
}
|
|
|
-}
|
|
|
+}
|