mirror of
https://github.com/pipipi-pikachu/PPTist.git
synced 2025-04-15 02:20:00 +08:00
feat: 更新导入功能(pptxtojson v0.1.2)
This commit is contained in:
parent
effd46e05e
commit
d03f3a9414
14
package-lock.json
generated
14
package-lock.json
generated
@ -24,7 +24,7 @@
|
||||
"number-precision": "^1.6.0",
|
||||
"pinia": "^2.1.7",
|
||||
"pptxgenjs": "^3.12.0",
|
||||
"pptxtojson": "^0.0.13",
|
||||
"pptxtojson": "^0.1.2",
|
||||
"prosemirror-commands": "^1.3.0",
|
||||
"prosemirror-dropcursor": "^1.6.0",
|
||||
"prosemirror-gapcursor": "^1.3.1",
|
||||
@ -10868,9 +10868,9 @@
|
||||
"integrity": "sha512-t3rNFBgJRugIhackit2mVcLfF6IRc0JE4oeizPQL8Zrm8n2WY/0wOdpOPhdtG0V9Q2TlW/axbF1MJ6z+Yj/kKQ=="
|
||||
},
|
||||
"node_modules/pptxtojson": {
|
||||
"version": "0.0.13",
|
||||
"resolved": "https://registry.npmmirror.com/pptxtojson/-/pptxtojson-0.0.13.tgz",
|
||||
"integrity": "sha512-ltwUe4U6UVvZ2/+4qhzz8LlH7VBox/Y454ppRPlQeMY/yqszpBdD2/Qj+WEslhrciVY+lup8K+7e7pbL9ZTJuQ==",
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/pptxtojson/-/pptxtojson-0.1.2.tgz",
|
||||
"integrity": "sha512-UvzEuCnspfZqc1Tf7TU6tSyXV+4OngkTfoAEZdPVW2i6wedU16wr8hkNzwQ77ePyfoyaODAFwS9cfJnnEhwfKQ==",
|
||||
"dependencies": {
|
||||
"jszip": "^3.10.1",
|
||||
"tinycolor2": "1.6.0",
|
||||
@ -23339,9 +23339,9 @@
|
||||
}
|
||||
},
|
||||
"pptxtojson": {
|
||||
"version": "0.0.13",
|
||||
"resolved": "https://registry.npmmirror.com/pptxtojson/-/pptxtojson-0.0.13.tgz",
|
||||
"integrity": "sha512-ltwUe4U6UVvZ2/+4qhzz8LlH7VBox/Y454ppRPlQeMY/yqszpBdD2/Qj+WEslhrciVY+lup8K+7e7pbL9ZTJuQ==",
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/pptxtojson/-/pptxtojson-0.1.2.tgz",
|
||||
"integrity": "sha512-UvzEuCnspfZqc1Tf7TU6tSyXV+4OngkTfoAEZdPVW2i6wedU16wr8hkNzwQ77ePyfoyaODAFwS9cfJnnEhwfKQ==",
|
||||
"requires": {
|
||||
"jszip": "^3.10.1",
|
||||
"tinycolor2": "1.6.0",
|
||||
|
@ -25,7 +25,7 @@
|
||||
"number-precision": "^1.6.0",
|
||||
"pinia": "^2.1.7",
|
||||
"pptxgenjs": "^3.12.0",
|
||||
"pptxtojson": "^0.0.13",
|
||||
"pptxtojson": "^0.1.2",
|
||||
"prosemirror-commands": "^1.3.0",
|
||||
"prosemirror-dropcursor": "^1.6.0",
|
||||
"prosemirror-gapcursor": "^1.3.1",
|
||||
|
@ -1,14 +1,25 @@
|
||||
import { ref } from 'vue'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { parse, type Shape, type Element } from 'pptxtojson'
|
||||
import { parse, type Shape, type Element, type ChartItem } from 'pptxtojson'
|
||||
import { nanoid } from 'nanoid'
|
||||
import type { Slide, TableCellStyle, TableCell, ChartType, ChartOptions, SlideBackground, PPTShapeElement, PPTLineElement } from '@/types/slides'
|
||||
import { useSlidesStore } from '@/store'
|
||||
import { decrypt } from '@/utils/crypto'
|
||||
import { type ShapePoolItem, SHAPE_LIST, SHAPE_PATH_FORMULAS } from '@/configs/shapes'
|
||||
import { VIEWPORT_SIZE } from '@/configs/canvas'
|
||||
import useAddSlidesOrElements from '@/hooks/useAddSlidesOrElements'
|
||||
import message from '@/utils/message'
|
||||
import type {
|
||||
Slide,
|
||||
TableCellStyle,
|
||||
TableCell,
|
||||
ChartType,
|
||||
ChartOptions,
|
||||
SlideBackground,
|
||||
PPTShapeElement,
|
||||
PPTLineElement,
|
||||
ShapeTextAlign,
|
||||
PPTTextElement,
|
||||
} from '@/types/slides'
|
||||
|
||||
export default () => {
|
||||
const slidesStore = useSlidesStore()
|
||||
@ -65,7 +76,7 @@ export default () => {
|
||||
top: el.top,
|
||||
start,
|
||||
end,
|
||||
style: el.borderType,
|
||||
style: el.borderType === 'solid' ? 'solid' : 'dashed',
|
||||
color: el.borderColor,
|
||||
points: ['', el.shapType === 'straightConnector1' ? 'arrow' : '']
|
||||
}
|
||||
@ -85,7 +96,10 @@ export default () => {
|
||||
|
||||
const reader = new FileReader()
|
||||
reader.onload = async e => {
|
||||
const json = await parse(e.target!.result as ArrayBuffer)
|
||||
const json = await parse(e.target!.result as ArrayBuffer, {
|
||||
slideFactor: 75 / 914400,
|
||||
fontsizeFactor: 100 / 98,
|
||||
})
|
||||
|
||||
const width = json.size.width
|
||||
const scale = VIEWPORT_SIZE / width
|
||||
@ -105,7 +119,7 @@ export default () => {
|
||||
background = {
|
||||
type: 'gradient',
|
||||
gradientType: 'linear',
|
||||
gradientColor: [value.colors[0], value.colors[1]],
|
||||
gradientColor: [value.colors[0].color, value.colors[value.colors.length - 1].color],
|
||||
gradientRotate: value.rot,
|
||||
}
|
||||
}
|
||||
@ -130,7 +144,7 @@ export default () => {
|
||||
el.top = el.top * scale
|
||||
|
||||
if (el.type === 'text') {
|
||||
slide.elements.push({
|
||||
const textEl: PPTTextElement = {
|
||||
type: 'text',
|
||||
id: nanoid(10),
|
||||
width: el.width,
|
||||
@ -145,10 +159,13 @@ export default () => {
|
||||
outline: {
|
||||
color: el.borderColor,
|
||||
width: el.borderWidth,
|
||||
style: el.borderType,
|
||||
style: el.borderType === 'solid' ? 'solid' : 'dashed',
|
||||
},
|
||||
fill: el.fillColor,
|
||||
})
|
||||
vertical: el.isVertical,
|
||||
}
|
||||
if (el.shadow) textEl.shadow = el.shadow
|
||||
slide.elements.push(textEl)
|
||||
}
|
||||
else if (el.type === 'image') {
|
||||
slide.elements.push({
|
||||
@ -163,13 +180,48 @@ export default () => {
|
||||
rotate: el.rotate,
|
||||
})
|
||||
}
|
||||
else if (el.type === 'audio') {
|
||||
slide.elements.push({
|
||||
type: 'audio',
|
||||
id: nanoid(10),
|
||||
src: el.blob,
|
||||
width: el.width,
|
||||
height: el.height,
|
||||
left: el.left,
|
||||
top: el.top,
|
||||
rotate: 0,
|
||||
fixedRatio: false,
|
||||
color: theme.value.themeColor,
|
||||
loop: false,
|
||||
autoplay: false,
|
||||
})
|
||||
}
|
||||
else if (el.type === 'video') {
|
||||
slide.elements.push({
|
||||
type: 'video',
|
||||
id: nanoid(10),
|
||||
src: (el.blob || el.src)!,
|
||||
width: el.width,
|
||||
height: el.height,
|
||||
left: el.left,
|
||||
top: el.top,
|
||||
rotate: 0,
|
||||
autoplay: false,
|
||||
})
|
||||
}
|
||||
else if (el.type === 'shape') {
|
||||
if (el.shapType === 'line' || el.shapType === 'straightConnector1') {
|
||||
if (el.shapType === 'line' || /Connector/.test(el.shapType)) {
|
||||
const lineElement = parseLineElement(el)
|
||||
slide.elements.push(lineElement)
|
||||
}
|
||||
else {
|
||||
const shape = shapeList.find(item => item.pptxShapeType === el.shapType)
|
||||
|
||||
const vAlignMap: { [key: string]: ShapeTextAlign } = {
|
||||
'mid': 'middle',
|
||||
'down': 'bottom',
|
||||
'up': 'top',
|
||||
}
|
||||
|
||||
const element: PPTShapeElement = {
|
||||
type: 'shape',
|
||||
@ -186,15 +238,18 @@ export default () => {
|
||||
outline: {
|
||||
color: el.borderColor,
|
||||
width: el.borderWidth,
|
||||
style: el.borderType,
|
||||
style: el.borderType === 'solid' ? 'solid' : 'dashed',
|
||||
},
|
||||
text: {
|
||||
content: el.content,
|
||||
defaultFontName: theme.value.fontName,
|
||||
defaultColor: theme.value.fontColor,
|
||||
align: 'middle',
|
||||
}
|
||||
align: vAlignMap[el.vAlign] || 'middle',
|
||||
},
|
||||
flipH: el.isFlipH,
|
||||
flipV: el.isFlipV,
|
||||
}
|
||||
if (el.shadow) element.shadow = el.shadow
|
||||
|
||||
if (shape) {
|
||||
element.path = shape.path
|
||||
@ -212,6 +267,11 @@ export default () => {
|
||||
else element.path = pathFormula.formula(el.width, el.height)
|
||||
}
|
||||
}
|
||||
if (el.shapType === 'custom') {
|
||||
element.special = true
|
||||
element.path = el.path!
|
||||
element.viewBox = [el.width, el.height]
|
||||
}
|
||||
|
||||
slide.elements.push(element)
|
||||
}
|
||||
@ -231,7 +291,7 @@ export default () => {
|
||||
const cellData = el.data[i][j]
|
||||
rowCells.push({
|
||||
id: nanoid(10),
|
||||
colspan: 1,
|
||||
colspan: cellData.colSpan || 1,
|
||||
rowspan: cellData.rowSpan || 1,
|
||||
text: cellData.text,
|
||||
style,
|
||||
@ -258,7 +318,7 @@ export default () => {
|
||||
color: '#eeece1',
|
||||
},
|
||||
theme: {
|
||||
color: theme.value.themeColor,
|
||||
color: el.themeColor,
|
||||
rowHeader: true,
|
||||
rowFooter: false,
|
||||
colHeader: false,
|
||||
@ -272,40 +332,47 @@ export default () => {
|
||||
let legends: string[]
|
||||
let series: number[][]
|
||||
|
||||
if (el.chartType === 'scatterChart') {
|
||||
labels = el.data[0].map(item => item + '')
|
||||
if (el.chartType === 'scatterChart' || el.chartType === 'bubbleChart') {
|
||||
const data = el.data
|
||||
labels = data[0].map(item => item + '')
|
||||
legends = ['系列1']
|
||||
series = [el.data[1]]
|
||||
series = [data[1]]
|
||||
}
|
||||
else {
|
||||
labels = Object.values(el.data[0].xlabels)
|
||||
legends = el.data.map(item => item.key)
|
||||
series = el.data.map(item => item.values.map(v => v.y))
|
||||
const data = el.data as ChartItem[]
|
||||
labels = Object.values(data[0].xlabels)
|
||||
legends = data.map(item => item.key)
|
||||
series = data.map(item => item.values.map(v => v.y))
|
||||
}
|
||||
|
||||
let options: ChartOptions = {}
|
||||
const options: ChartOptions = {}
|
||||
|
||||
let chartType: ChartType = 'bar'
|
||||
if (el.chartType === 'barChart') {
|
||||
chartType = 'bar'
|
||||
}
|
||||
if (el.chartType === 'stackedBarChart') {
|
||||
chartType = 'bar'
|
||||
options = { stackBars: true }
|
||||
}
|
||||
else if (el.chartType === 'lineChart') {
|
||||
chartType = 'line'
|
||||
}
|
||||
else if (el.chartType === 'areaChart') {
|
||||
chartType = 'line'
|
||||
options = { showArea: true }
|
||||
}
|
||||
else if (el.chartType === 'scatterChart') {
|
||||
chartType = 'line'
|
||||
options = { showLine: false }
|
||||
}
|
||||
else if (el.chartType === 'pieChart' || el.chartType === 'pie3DChart') {
|
||||
chartType = 'pie'
|
||||
|
||||
switch (el.chartType) {
|
||||
case 'barChart':
|
||||
case 'bar3DChart':
|
||||
chartType = 'bar'
|
||||
if (el.barDir === 'bar') options.horizontalBars = true
|
||||
if (el.grouping === 'stacked' || el.grouping === 'percentStacked') options.stackBars = true
|
||||
break
|
||||
case 'lineChart':
|
||||
case 'line3DChart':
|
||||
case 'areaChart':
|
||||
case 'area3DChart':
|
||||
case 'scatterChart':
|
||||
case 'bubbleChart':
|
||||
chartType = 'line'
|
||||
if (el.chartType === 'areaChart' || el.chartType === 'area3DChart') options.showArea = true
|
||||
if (el.chartType === 'scatterChart' || el.chartType === 'bubbleChart') options.showLine = false
|
||||
break
|
||||
case 'pieChart':
|
||||
case 'pie3DChart':
|
||||
case 'doughnutChart':
|
||||
chartType = 'pie'
|
||||
if (el.chartType === 'doughnutChart') options.donut = true
|
||||
break
|
||||
default:
|
||||
}
|
||||
|
||||
slide.elements.push({
|
||||
@ -327,7 +394,7 @@ export default () => {
|
||||
options,
|
||||
})
|
||||
}
|
||||
else if (el.type === 'group') {
|
||||
else if (el.type === 'group' || el.type === 'diagram') {
|
||||
const elements = el.elements.map(_el => ({
|
||||
..._el,
|
||||
left: _el.left + el.left,
|
||||
|
@ -266,6 +266,8 @@ export interface ShapeGradient {
|
||||
rotate: number
|
||||
}
|
||||
|
||||
export type ShapeTextAlign = 'top' | 'middle' | 'bottom'
|
||||
|
||||
/**
|
||||
* 形状内文本
|
||||
*
|
||||
@ -281,7 +283,7 @@ export interface ShapeText {
|
||||
content: string
|
||||
defaultFontName: string
|
||||
defaultColor: string
|
||||
align: 'top' | 'middle' | 'bottom'
|
||||
align: ShapeTextAlign
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user