mirror of
https://github.com/pipipi-pikachu/PPTist.git
synced 2025-04-15 02:20:00 +08:00
feat: 导入PPTX文件DEMO
This commit is contained in:
parent
c7c5de1de2
commit
0025a12f43
99
package-lock.json
generated
99
package-lock.json
generated
@ -24,6 +24,7 @@
|
||||
"nanoid": "^4.0.0",
|
||||
"pinia": "^2.0.32",
|
||||
"pptxgenjs": "^3.11.0",
|
||||
"pptxtojson": "^0.0.8",
|
||||
"prosemirror-commands": "^1.3.0",
|
||||
"prosemirror-dropcursor": "^1.6.0",
|
||||
"prosemirror-gapcursor": "^1.3.1",
|
||||
@ -40,8 +41,7 @@
|
||||
"svg-arc-to-cubic-bezier": "^3.2.0",
|
||||
"svg-pathdata": "^6.0.0",
|
||||
"tinycolor2": "^1.6.0",
|
||||
"vue": "^3.2.47",
|
||||
"vuedraggable": "^4.1.0"
|
||||
"vue": "^3.2.47"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^17.4.4",
|
||||
@ -11734,6 +11734,16 @@
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/pptxtojson": {
|
||||
"version": "0.0.8",
|
||||
"resolved": "https://registry.npmjs.org/pptxtojson/-/pptxtojson-0.0.8.tgz",
|
||||
"integrity": "sha512-9RDoPhTF9Nq7xlJbzmi05lfLV4TVa7sATX5uUmzWEj5mZyQ1SymIU8e6E1/h86/4BUVB0DbM9blwjCBXjiVlpw==",
|
||||
"dependencies": {
|
||||
"jszip": "^3.10.1",
|
||||
"tinycolor2": "1.6.0",
|
||||
"txml": "^5.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/prelude-ls": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
|
||||
@ -12278,7 +12288,6 @@
|
||||
"version": "3.6.1",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.1.tgz",
|
||||
"integrity": "sha512-+rQmrWMYGA90yenhTYsLWAsLsqVC8osOw6PKE1HDYiO0gdPeKe/xDHNzIAIn4C91YQ6oenEhfYqqc1883qHbjQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
@ -12689,7 +12698,6 @@
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@ -13338,7 +13346,6 @@
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
||||
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"safe-buffer": "~5.2.0"
|
||||
}
|
||||
@ -14395,6 +14402,23 @@
|
||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/txml": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/txml/-/txml-5.1.1.tgz",
|
||||
"integrity": "sha512-TwMDLnXQ09enNaxybLVvKZU7rqog8LgnuAs4ZYXM0nV0eu10iLsSFwlX3AEknAXXtH1wT3CYfoiXAjyBexcmuw==",
|
||||
"dependencies": {
|
||||
"through2": "^3.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/txml/node_modules/through2": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/through2/-/through2-3.0.2.tgz",
|
||||
"integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==",
|
||||
"dependencies": {
|
||||
"inherits": "^2.0.4",
|
||||
"readable-stream": "2 || 3"
|
||||
}
|
||||
},
|
||||
"node_modules/type-check": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
|
||||
@ -14887,22 +14911,6 @@
|
||||
"vue": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vuedraggable": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/vuedraggable/-/vuedraggable-4.1.0.tgz",
|
||||
"integrity": "sha512-FU5HCWBmsf20GpP3eudURW3WdWTKIbEIQxh9/8GE806hydR9qZqRRxRE3RjqX7PkuLuMQG/A7n3cfj9rCEchww==",
|
||||
"dependencies": {
|
||||
"sortablejs": "1.14.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "^3.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/vuedraggable/node_modules/sortablejs": {
|
||||
"version": "1.14.0",
|
||||
"resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.14.0.tgz",
|
||||
"integrity": "sha512-pBXvQCs5/33fdN1/39pPL0NZF20LeRbLQ5jtnheIPN9JQAaufGjKdWduZn4U7wCtVuzKhmRkI0DFYHYRbB2H1w=="
|
||||
},
|
||||
"node_modules/w3c-keyname": {
|
||||
"version": "2.2.6",
|
||||
"resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.6.tgz",
|
||||
@ -24667,6 +24675,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"pptxtojson": {
|
||||
"version": "0.0.8",
|
||||
"resolved": "https://registry.npmjs.org/pptxtojson/-/pptxtojson-0.0.8.tgz",
|
||||
"integrity": "sha512-9RDoPhTF9Nq7xlJbzmi05lfLV4TVa7sATX5uUmzWEj5mZyQ1SymIU8e6E1/h86/4BUVB0DbM9blwjCBXjiVlpw==",
|
||||
"requires": {
|
||||
"jszip": "^3.10.1",
|
||||
"tinycolor2": "1.6.0",
|
||||
"txml": "^5.1.1"
|
||||
}
|
||||
},
|
||||
"prelude-ls": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
|
||||
@ -25104,7 +25122,6 @@
|
||||
"version": "3.6.1",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.1.tgz",
|
||||
"integrity": "sha512-+rQmrWMYGA90yenhTYsLWAsLsqVC8osOw6PKE1HDYiO0gdPeKe/xDHNzIAIn4C91YQ6oenEhfYqqc1883qHbjQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
@ -25406,8 +25423,7 @@
|
||||
"safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
|
||||
},
|
||||
"safe-regex-test": {
|
||||
"version": "1.0.0",
|
||||
@ -25928,7 +25944,6 @@
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
||||
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safe-buffer": "~5.2.0"
|
||||
}
|
||||
@ -26708,6 +26723,25 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"txml": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/txml/-/txml-5.1.1.tgz",
|
||||
"integrity": "sha512-TwMDLnXQ09enNaxybLVvKZU7rqog8LgnuAs4ZYXM0nV0eu10iLsSFwlX3AEknAXXtH1wT3CYfoiXAjyBexcmuw==",
|
||||
"requires": {
|
||||
"through2": "^3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"through2": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/through2/-/through2-3.0.2.tgz",
|
||||
"integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==",
|
||||
"requires": {
|
||||
"inherits": "^2.0.4",
|
||||
"readable-stream": "2 || 3"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"type-check": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
|
||||
@ -27071,21 +27105,6 @@
|
||||
"is-plain-object": "3.0.1"
|
||||
}
|
||||
},
|
||||
"vuedraggable": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/vuedraggable/-/vuedraggable-4.1.0.tgz",
|
||||
"integrity": "sha512-FU5HCWBmsf20GpP3eudURW3WdWTKIbEIQxh9/8GE806hydR9qZqRRxRE3RjqX7PkuLuMQG/A7n3cfj9rCEchww==",
|
||||
"requires": {
|
||||
"sortablejs": "1.14.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"sortablejs": {
|
||||
"version": "1.14.0",
|
||||
"resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.14.0.tgz",
|
||||
"integrity": "sha512-pBXvQCs5/33fdN1/39pPL0NZF20LeRbLQ5jtnheIPN9JQAaufGjKdWduZn4U7wCtVuzKhmRkI0DFYHYRbB2H1w=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"w3c-keyname": {
|
||||
"version": "2.2.6",
|
||||
"resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.6.tgz",
|
||||
|
@ -25,6 +25,7 @@
|
||||
"nanoid": "^4.0.0",
|
||||
"pinia": "^2.0.32",
|
||||
"pptxgenjs": "^3.11.0",
|
||||
"pptxtojson": "^0.0.8",
|
||||
"prosemirror-commands": "^1.3.0",
|
||||
"prosemirror-dropcursor": "^1.6.0",
|
||||
"prosemirror-gapcursor": "^1.3.1",
|
||||
|
@ -10,6 +10,7 @@ export interface ShapePoolItem {
|
||||
special?: boolean
|
||||
pathFormula?: ShapePathFormulasKeys
|
||||
outlined?: boolean
|
||||
pptxShapeType?: string
|
||||
}
|
||||
|
||||
interface ShapeListItem {
|
||||
@ -228,47 +229,56 @@ export const SHAPE_LIST: ShapeListItem[] = [
|
||||
children: [
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
path: 'M 0 0 L 200 0 L 200 200 L 0 200 Z'
|
||||
path: 'M 0 0 L 200 0 L 200 200 L 0 200 Z',
|
||||
pptxShapeType: 'rect',
|
||||
},
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
path: 'M 50 0 L 150 0 Q 200 0 200 50 L 200 150 Q 200 200 150 200 L 50 200 Q 0 200 0 150 L 0 50 Q 0 0 50 0 Z',
|
||||
pathFormula: ShapePathFormulasKeys.ROUND_RECT,
|
||||
pptxShapeType: 'roundRect',
|
||||
},
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
path: 'M 0 200 L 0 0 L 150 0 L 200 50 L 200 200 Z',
|
||||
pathFormula: ShapePathFormulasKeys.CUT_RECT_SINGLE,
|
||||
pptxShapeType: 'snip1Rect',
|
||||
},
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
path: 'M 0 50 L 50 0 L 150 0 L 200 50 L 200 200 L 0 200 Z',
|
||||
pathFormula: ShapePathFormulasKeys.CUT_RECT_SAMESIDE,
|
||||
pptxShapeType: 'snip2SameRect',
|
||||
},
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
path: 'M 0 150 L 0 0 L 150 0 L 200 50 L 200 200 L 50 200 Z',
|
||||
pathFormula: ShapePathFormulasKeys.CUT_RECT_DIAGONAL,
|
||||
pptxShapeType: 'snip2DiagRect',
|
||||
},
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
path: 'M 50 0 L 150 0 L 200 50 L 200 200 L 0 200 L 0 50 Q 0 0 50 0 Z',
|
||||
pathFormula: ShapePathFormulasKeys.CUT_ROUND_RECT,
|
||||
pptxShapeType: 'snipRoundRect',
|
||||
},
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
path: 'M 0 0 L 150 0 Q 200 0 200 50 L 200 200 L 0 200 L 0 0 Z',
|
||||
pathFormula: ShapePathFormulasKeys.ROUND_RECT_SINGLE,
|
||||
pptxShapeType: 'round1Rect',
|
||||
},
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
path: 'M 0 50 Q 0 0 50 0 L 150 0 Q 200 0 200 50 L 200 200 L 0 200 Z',
|
||||
pathFormula: ShapePathFormulasKeys.ROUND_RECT_SAMESIDE,
|
||||
pptxShapeType: 'round2SameRect',
|
||||
},
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
path: 'M 50 0 L 200 0 L 200 150 Q 200 200 150 200 L 0 200 L 0 50 Q 0 0 50 0 Z',
|
||||
pathFormula: ShapePathFormulasKeys.ROUND_RECT_DIAGONAL,
|
||||
pptxShapeType: 'round2DiagRect',
|
||||
},
|
||||
]
|
||||
},
|
||||
@ -278,12 +288,14 @@ export const SHAPE_LIST: ShapeListItem[] = [
|
||||
children: [
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
path: 'M 100 0 A 50 50 0 1 1 100 200 A 50 50 0 1 1 100 0 Z'
|
||||
path: 'M 100 0 A 50 50 0 1 1 100 200 A 50 50 0 1 1 100 0 Z',
|
||||
pptxShapeType: 'ellipse',
|
||||
},
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
path: 'M 100 0 L 0 200 L 200 200 L 100 0 Z',
|
||||
pathFormula: ShapePathFormulasKeys.TRIANGLE,
|
||||
pptxShapeType: 'triangle',
|
||||
},
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
@ -297,6 +309,7 @@ export const SHAPE_LIST: ShapeListItem[] = [
|
||||
viewBox: [200, 200],
|
||||
path: 'M 50 0 L 200 0 L 150 200 L 0 200 L 50 0 Z',
|
||||
pathFormula: ShapePathFormulasKeys.PARALLELOGRAM_LEFT,
|
||||
pptxShapeType: 'parallelogram',
|
||||
},
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
@ -307,10 +320,12 @@ export const SHAPE_LIST: ShapeListItem[] = [
|
||||
viewBox: [200, 200],
|
||||
path: 'M 50 0 L 150 0 L 200 200 L 0 200 L 50 0 Z',
|
||||
pathFormula: ShapePathFormulasKeys.TRAPEZOID,
|
||||
pptxShapeType: 'trapezoid',
|
||||
},
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
path: 'M 100 0 L 0 100 L 100 200 L 200 100 L 100 0 Z'
|
||||
path: 'M 100 0 L 0 100 L 100 200 L 200 100 L 100 0 Z',
|
||||
pptxShapeType: 'diamond',
|
||||
},
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
@ -340,7 +355,8 @@ export const SHAPE_LIST: ShapeListItem[] = [
|
||||
},
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
path: 'M 100 0 A 100 100 102 1 0 200 100 L 100 100 L 100 0 Z'
|
||||
path: 'M 100 0 A 100 100 102 1 0 200 100 L 100 100 L 100 0 Z',
|
||||
pptxShapeType: 'pie',
|
||||
},
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
@ -348,11 +364,13 @@ export const SHAPE_LIST: ShapeListItem[] = [
|
||||
},
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
path: 'M 100 0 A 100 100 102 1 0 200 100 L 100 0 Z'
|
||||
path: 'M 100 0 A 100 100 102 1 0 200 100 L 100 0 Z',
|
||||
pptxShapeType: 'chord',
|
||||
},
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
path: 'M 100 0 A 100 100 102 1 0 200 100 L 200 0 L 100 0 Z'
|
||||
path: 'M 100 0 A 100 100 102 1 0 200 100 L 200 0 L 100 0 Z',
|
||||
pptxShapeType: 'teardrop',
|
||||
},
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
@ -360,7 +378,13 @@ export const SHAPE_LIST: ShapeListItem[] = [
|
||||
},
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
path: 'M 100 0 L 0 90 L 50 200 L 150 200 L 200 90 L 100 0 Z'
|
||||
path: 'M 100 0 L 0 90 L 50 200 L 150 200 L 200 90 L 100 0 Z',
|
||||
pptxShapeType: 'pentagon',
|
||||
},
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
path: 'M 40 0 L 160 0 L 200 100 L 160 200 L 40 200 L 0 100 Z',
|
||||
pptxShapeType: 'hexagon',
|
||||
},
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
@ -368,7 +392,8 @@ export const SHAPE_LIST: ShapeListItem[] = [
|
||||
},
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
path: 'M 60 0 L 140 0 L 200 60 L 200 140 L 140 200 L 60 200 L 0 140 L 0 60 L 60 0 Z'
|
||||
path: 'M 60 0 L 140 0 L 200 60 L 200 140 L 140 200 L 60 200 L 0 140 L 0 60 L 60 0 Z',
|
||||
pptxShapeType: 'octagon',
|
||||
},
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
@ -462,6 +487,13 @@ export const SHAPE_LIST: ShapeListItem[] = [
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
path: 'M 100 0 L 120 80 L 200 100 L 120 120 L 100 200 L 80 120 L 0 100 L 80 80 L 100 0 Z',
|
||||
pptxShapeType: 'star4',
|
||||
},
|
||||
{
|
||||
viewBox: [1024, 1024],
|
||||
path: 'M1018.67652554 400.05983681l-382.95318779-5.89158658L512 34.78141155 388.27666225 394.16825023l-382.95318779 5.89158658L311.68602415 629.83174977l-117.83174978 365.27842665 312.25413766-223.88032637 312.25413904 223.88032637-117.83175116-365.27842665 318.14572563-229.77191296z',
|
||||
pptxShapeType: 'star5',
|
||||
special: true,
|
||||
},
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
@ -470,6 +502,7 @@ export const SHAPE_LIST: ShapeListItem[] = [
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
path: 'M 100 0 L 140 60 L 200 60 L 160 100 L 200 140 L 140 140 L 100 200 L 60 140 L 0 140 L 40 100 L 0 60 L 60 60 L 100 0 Z',
|
||||
pptxShapeType: 'star6',
|
||||
},
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
@ -487,27 +520,33 @@ export const SHAPE_LIST: ShapeListItem[] = [
|
||||
children: [
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
path: 'M 100 0 L 0 100 L 50 100 L 50 200 L 150 200 L 150 100 L 200 100 L 100 0 Z'
|
||||
path: 'M 100 0 L 0 100 L 50 100 L 50 200 L 150 200 L 150 100 L 200 100 L 100 0 Z',
|
||||
pptxShapeType: 'upArrow',
|
||||
},
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
path: 'M 100 200 L 200 100 L 150 100 L 150 0 L 50 0 L 50 100 L 0 100 L 100 200 Z'
|
||||
path: 'M 100 200 L 200 100 L 150 100 L 150 0 L 50 0 L 50 100 L 0 100 L 100 200 Z',
|
||||
pptxShapeType: 'downArrow',
|
||||
},
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
path: 'M 0 100 L 100 0 L 100 50 L 200 50 L 200 150 L 100 150 L 100 200 L 0 100 Z'
|
||||
path: 'M 0 100 L 100 0 L 100 50 L 200 50 L 200 150 L 100 150 L 100 200 L 0 100 Z',
|
||||
pptxShapeType: 'leftArrow',
|
||||
},
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
path: 'M 200 100 L 100 0 L 100 50 L 0 50 L 0 150 L 100 150 L 100 200 L 200 100 Z'
|
||||
path: 'M 200 100 L 100 0 L 100 50 L 0 50 L 0 150 L 100 150 L 100 200 L 200 100 Z',
|
||||
pptxShapeType: 'rightArrow',
|
||||
},
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
path: 'M 100 0 L 0 60 L 60 60 L 60 140 L 0 140 L 100 200 L 200 140 L 140 140 L 140 60 L 200 60 L 100 0 Z'
|
||||
path: 'M 100 0 L 0 60 L 60 60 L 60 140 L 0 140 L 100 200 L 200 140 L 140 140 L 140 60 L 200 60 L 100 0 Z',
|
||||
pptxShapeType: 'upDownArrow',
|
||||
},
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
path: 'M 0 100 L 60 0 L 60 60 L 140 60 L 140 0 L 200 100 L 140 200 L 140 140 L 60 140 L 60 200 L 0 100 Z'
|
||||
path: 'M 0 100 L 60 0 L 60 60 L 140 60 L 140 0 L 200 100 L 140 200 L 140 140 L 60 140 L 60 200 L 0 100 Z',
|
||||
pptxShapeType: 'leftRightArrow',
|
||||
},
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
@ -515,11 +554,12 @@ export const SHAPE_LIST: ShapeListItem[] = [
|
||||
},
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
path: 'M 0 100 L 100 0 L 100 50 L 200 50 L 150 100 L 200 150 L 100 150 L 100 200 L 0 100 Z'
|
||||
path: 'M 0 100 L 100 0 L 100 50 L 200 50 L 150 100 L 200 150 L 100 150 L 100 200 L 0 100 Z',
|
||||
},
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
path: 'M 200 100 L 100 0 L 100 50 L 0 50 L 50 100 L 0 150 L 100 150 L 100 200 L 200 100 Z'
|
||||
path: 'M 200 100 L 100 0 L 100 50 L 0 50 L 50 100 L 0 150 L 100 150 L 100 200 L 200 100 Z',
|
||||
pptxShapeType: 'notchedRightArrow',
|
||||
},
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
@ -527,19 +567,21 @@ export const SHAPE_LIST: ShapeListItem[] = [
|
||||
},
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
path: 'M 200 100 L 120 20 L 120 80 L 80 80 L 80 0 L 0 0 L 0 200 L 80 200 L 80 120 L 120 120 L 120 180 L 200 100 Z'
|
||||
path: 'M 200 100 L 120 20 L 120 80 L 80 80 L 80 0 L 0 0 L 0 200 L 80 200 L 80 120 L 120 120 L 120 180 L 200 100 Z',
|
||||
},
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
path: 'M 0 0 L 120 0 L 200 100 L 120 200 L 0 200 L 80 100 L 0 0 Z'
|
||||
path: 'M 0 0 L 120 0 L 200 100 L 120 200 L 0 200 L 80 100 L 0 0 Z',
|
||||
pptxShapeType: 'chevron',
|
||||
},
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
path: 'M 80 0 L 200 0 L 120 100 L 200 200 L 80 200 L 0 100 L 80 0 Z'
|
||||
path: 'M 80 0 L 200 0 L 120 100 L 200 200 L 80 200 L 0 100 L 80 0 Z',
|
||||
},
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
path: 'M 0 0 L 140 0 L 200 100 L 140 200 L 0 200 L 0 100 L 0 0 Z'
|
||||
path: 'M 0 0 L 140 0 L 200 100 L 140 200 L 0 200 L 0 100 L 0 0 Z',
|
||||
pptxShapeType: 'homePlate',
|
||||
},
|
||||
{
|
||||
viewBox: [200, 200],
|
||||
|
@ -10,10 +10,9 @@ import { PPTElementOutline, PPTElementShadow, PPTElementLink, Slide } from '@/ty
|
||||
import { getElementRange, getLineElementPath, getTableSubThemeColor } from '@/utils/element'
|
||||
import { AST, toAST } from '@/utils/htmlParser'
|
||||
import { SvgPoints, toPoints } from '@/utils/svgPathParser'
|
||||
import { decrypt, encrypt } from '@/utils/crypto'
|
||||
import { encrypt } from '@/utils/crypto'
|
||||
import { svg2Base64 } from '@/utils/svg2Base64'
|
||||
import { message } from 'ant-design-vue'
|
||||
import useAddSlidesOrElements from '@/hooks/useAddSlidesOrElements'
|
||||
|
||||
const INCH_PX_RATIO = 100
|
||||
const PT_PX_RATIO = 0.75
|
||||
@ -28,8 +27,6 @@ export default () => {
|
||||
const slidesStore = useSlidesStore()
|
||||
const { slides, theme, viewportRatio } = storeToRefs(slidesStore)
|
||||
|
||||
const { addSlidesFromData } = useAddSlidesOrElements()
|
||||
|
||||
const exporting = ref(false)
|
||||
|
||||
// 导出图片
|
||||
@ -64,24 +61,6 @@ export default () => {
|
||||
saveAs(blob, 'pptist_slides.pptist')
|
||||
}
|
||||
|
||||
// 导入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.setSlides(slides)
|
||||
else addSlidesFromData(slides)
|
||||
}
|
||||
catch {
|
||||
message.error('无法正确读取 / 解析该文件')
|
||||
}
|
||||
})
|
||||
reader.readAsText(file)
|
||||
}
|
||||
|
||||
// 导出JSON文件
|
||||
const exportJSON = () => {
|
||||
const blob = new Blob([JSON.stringify(slides.value)], { type: '' })
|
||||
@ -778,7 +757,6 @@ export default () => {
|
||||
exporting,
|
||||
exportImage,
|
||||
exportJSON,
|
||||
importSpecificFile,
|
||||
exportSpecificFile,
|
||||
exportPPTX,
|
||||
}
|
||||
|
266
src/hooks/useImport.ts
Normal file
266
src/hooks/useImport.ts
Normal file
@ -0,0 +1,266 @@
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { parse } from 'pptxtojson'
|
||||
import { nanoid } from 'nanoid'
|
||||
import { Slide, TableCellStyle, TableCell, ChartType, ChartOptions, SlideBackground, PPTShapeElement } from '@/types/slides'
|
||||
import { useSlidesStore } from '@/store'
|
||||
import { decrypt } from '@/utils/crypto'
|
||||
import { ShapePoolItem, SHAPE_LIST, SHAPE_PATH_FORMULAS } from '@/configs/shapes'
|
||||
import useAddSlidesOrElements from '@/hooks/useAddSlidesOrElements'
|
||||
|
||||
import { message } from 'ant-design-vue'
|
||||
|
||||
export default () => {
|
||||
const slidesStore = useSlidesStore()
|
||||
const { theme } = storeToRefs(useSlidesStore())
|
||||
|
||||
const { addSlidesFromData } = useAddSlidesOrElements()
|
||||
|
||||
// 导入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.setSlides(slides)
|
||||
else addSlidesFromData(slides)
|
||||
}
|
||||
catch {
|
||||
message.error('无法正确读取 / 解析该文件')
|
||||
}
|
||||
})
|
||||
reader.readAsText(file)
|
||||
}
|
||||
|
||||
// 导入PPTX文件
|
||||
const importPPTXFile = (files: FileList) => {
|
||||
const file = files[0]
|
||||
if (!file) return
|
||||
|
||||
const shapeList: ShapePoolItem[] = []
|
||||
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)
|
||||
const slides: Slide[] = []
|
||||
for (const item of json.slides) {
|
||||
const { type, value } = item.fill
|
||||
let background: SlideBackground
|
||||
if (type === 'image') {
|
||||
background = {
|
||||
type: 'image',
|
||||
image: value.picBase64,
|
||||
imageSize: 'cover',
|
||||
}
|
||||
}
|
||||
else {
|
||||
background = {
|
||||
type: 'solid',
|
||||
color: value,
|
||||
}
|
||||
}
|
||||
|
||||
const slide: Slide = {
|
||||
id: nanoid(10),
|
||||
elements: [],
|
||||
background,
|
||||
}
|
||||
for (const el of item.elements) {
|
||||
if (el.type === 'text') {
|
||||
slide.elements.push({
|
||||
type: 'text',
|
||||
id: nanoid(10),
|
||||
width: el.width,
|
||||
height: el.height,
|
||||
left: el.left,
|
||||
top: el.top,
|
||||
rotate: el.rotate,
|
||||
defaultFontName: theme.value.fontName,
|
||||
defaultColor: theme.value.fontColor,
|
||||
content: el.content,
|
||||
lineHeight: 1,
|
||||
outline: {
|
||||
color: el.borderColor,
|
||||
width: el.borderWidth,
|
||||
style: el.borderType,
|
||||
},
|
||||
fill: el.fillColor,
|
||||
})
|
||||
}
|
||||
else if (el.type === 'image') {
|
||||
slide.elements.push({
|
||||
type: 'image',
|
||||
id: nanoid(10),
|
||||
src: el.src,
|
||||
width: el.width,
|
||||
height: el.height,
|
||||
left: el.left,
|
||||
top: el.top,
|
||||
fixedRatio: true,
|
||||
rotate: el.rotate,
|
||||
})
|
||||
}
|
||||
else if (el.type === 'shape') {
|
||||
const shape = shapeList.find(item => item.pptxShapeType === el.shapType)
|
||||
|
||||
const element: PPTShapeElement = {
|
||||
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,
|
||||
fixedRatio: false,
|
||||
rotate: el.rotate,
|
||||
outline: {
|
||||
color: el.borderColor,
|
||||
width: el.borderWidth,
|
||||
style: el.borderType,
|
||||
},
|
||||
text: {
|
||||
content: el.content,
|
||||
defaultFontName: theme.value.fontName,
|
||||
defaultColor: theme.value.fontColor,
|
||||
align: 'middle',
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
element.path = pathFormula.formula(el.width, el.height, pathFormula.defaultValue)
|
||||
element.keypoint = pathFormula.defaultValue
|
||||
}
|
||||
else element.path = pathFormula.formula(el.width, el.height)
|
||||
}
|
||||
}
|
||||
|
||||
slide.elements.push(element)
|
||||
}
|
||||
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,
|
||||
}
|
||||
const data: TableCell[][] = []
|
||||
for (let i = 0; i < row; i++) {
|
||||
const rowCells: TableCell[] = []
|
||||
for (let j = 0; j < col; j++) {
|
||||
const cellData = el.data[i][j]
|
||||
rowCells.push({
|
||||
id: nanoid(10),
|
||||
colspan: 1,
|
||||
rowspan: cellData.rowSpan || 1,
|
||||
text: cellData.text,
|
||||
style,
|
||||
})
|
||||
}
|
||||
data.push(rowCells)
|
||||
}
|
||||
|
||||
const colWidths: number[] = new Array(col).fill(1 / col)
|
||||
|
||||
slide.elements.push({
|
||||
type: 'table',
|
||||
id: nanoid(10),
|
||||
width: el.width,
|
||||
height: el.height,
|
||||
left: el.left,
|
||||
top: el.top,
|
||||
colWidths,
|
||||
rotate: 0,
|
||||
data,
|
||||
outline: {
|
||||
width: 2,
|
||||
style: 'solid',
|
||||
color: '#eeece1',
|
||||
},
|
||||
theme: {
|
||||
color: theme.value.themeColor,
|
||||
rowHeader: true,
|
||||
rowFooter: false,
|
||||
colHeader: false,
|
||||
colFooter: false,
|
||||
},
|
||||
cellMinHeight: 36,
|
||||
})
|
||||
}
|
||||
else if (el.type === 'chart') {
|
||||
const labels = Object.values(el.data[0].xlabels)
|
||||
const legends = el.data.map(item => item.key)
|
||||
const series = el.data.map(item => item.values.map(v => v.y))
|
||||
let 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'
|
||||
}
|
||||
|
||||
slide.elements.push({
|
||||
type: 'chart',
|
||||
id: nanoid(10),
|
||||
chartType: chartType,
|
||||
width: el.width,
|
||||
height: el.height,
|
||||
left: el.left,
|
||||
top: el.top,
|
||||
rotate: 0,
|
||||
themeColor: [theme.value.themeColor],
|
||||
gridColor: theme.value.fontColor,
|
||||
data: {
|
||||
labels,
|
||||
legends,
|
||||
series,
|
||||
},
|
||||
options,
|
||||
})
|
||||
}
|
||||
// else if (el.type === 'group') {}
|
||||
}
|
||||
slides.push(slide)
|
||||
}
|
||||
addSlidesFromData(slides)
|
||||
}
|
||||
reader.readAsArrayBuffer(file)
|
||||
}
|
||||
|
||||
return {
|
||||
importSpecificFile,
|
||||
importPPTXFile,
|
||||
}
|
||||
}
|
@ -8,6 +8,9 @@
|
||||
<FileInput accept=".pptist" @change="files => importSpecificFile(files)">
|
||||
<MenuItem>导入 pptist 文件</MenuItem>
|
||||
</FileInput>
|
||||
<FileInput accept="application/vnd.openxmlformats-officedocument.presentationml.presentation" @change="files => importPPTXFile(files)">
|
||||
<MenuItem>导入 pptx 文件(demo)</MenuItem>
|
||||
</FileInput>
|
||||
<MenuItem @click="setDialogForExport('pptx')">导出文件</MenuItem>
|
||||
</Menu>
|
||||
</template>
|
||||
@ -83,7 +86,7 @@ import { useMainStore } from '@/store'
|
||||
import useScreening from '@/hooks/useScreening'
|
||||
import useSlideHandler from '@/hooks/useSlideHandler'
|
||||
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
|
||||
import useExport from '@/hooks/useExport'
|
||||
import useImport from '@/hooks/useImport'
|
||||
|
||||
import HotkeyDoc from './HotkeyDoc.vue'
|
||||
import FileInput from '@/components/FileInput.vue'
|
||||
@ -101,7 +104,7 @@ const { gridLineSize, showRuler, showSelectPanel } = storeToRefs(mainStore)
|
||||
const { enterScreening, enterScreeningFromStart } = useScreening()
|
||||
const { createSlide, deleteSlide, resetSlides } = useSlideHandler()
|
||||
const { redo, undo } = useHistorySnapshot()
|
||||
const { importSpecificFile } = useExport()
|
||||
const { importSpecificFile, importPPTXFile } = useImport()
|
||||
|
||||
const setDialogForExport = mainStore.setDialogForExport
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user