-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Expand file tree
/
Copy pathindex.vue
More file actions
146 lines (141 loc) · 4.02 KB
/
index.vue
File metadata and controls
146 lines (141 loc) · 4.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
<template>
<el-dialog
v-model="dialogVisible"
:title="$t('chat.preview')"
style="overflow: auto"
width="80%"
:before-close="close"
destroy-on-close
>
<div
v-loading="loading"
style="height: calc(70vh - 150px); overflow-y: auto; display: flex; justify-content: center"
>
<div ref="svgContainerRef"></div>
</div>
<template #footer>
<span class="dialog-footer">
<el-button :loading="loading" @click="exportPDF">{{ $t('chat.exportPDF') }}</el-button>
<el-button
:loading="loading"
type="primary"
@click="
() => {
loading = true
exportJepg()
}
"
>
{{ $t('chat.exportImg') }}
</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import * as htmlToImage from 'html-to-image'
import { ref, nextTick } from 'vue'
import html2Canvas from 'html2canvas'
import { jsPDF } from 'jspdf'
const loading = ref<boolean>(false)
const svgContainerRef = ref()
const dialogVisible = ref<boolean>(false)
const open = (element: HTMLElement | null) => {
dialogVisible.value = true
loading.value = true
if (!element) {
return
}
setTimeout(() => {
nextTick(() => {
htmlToImage
.toSvg(element, { pixelRatio: 1, quality: 1 })
.then((dataUrl) => {
return fetch(dataUrl)
.then((response) => {
return response.text()
})
.then((text) => {
const parser = new DOMParser()
const svgDoc = parser.parseFromString(text, 'image/svg+xml')
const svgElement = svgDoc.documentElement
svgContainerRef.value.appendChild(svgElement)
svgContainerRef.value.style.height = svgElement.scrollHeight + 'px'
})
})
.finally(() => {
loading.value = false
})
})
}, 1)
}
const exportPDF = () => {
loading.value = true
setTimeout(() => {
nextTick(() => {
html2Canvas(svgContainerRef.value, {
logging: false,
})
.then((canvas) => {
const doc = new jsPDF('p', 'mm', 'a4')
// 将canvas转换为图片
const imgData = canvas.toDataURL(`image/jpeg`, 1)
// 获取PDF页面尺寸
const pageWidth = doc.internal.pageSize.getWidth()
const pageHeight = doc.internal.pageSize.getHeight()
// 计算图像在PDF中的尺寸
const imgWidth = pageWidth
const imgHeight = (canvas.height * imgWidth) / canvas.width
// 添加图像到PDF
doc.addImage(imgData, 'jpeg', 0, 0, imgWidth, imgHeight)
// 如果内容超过一页,自动添加新页面
let heightLeft = imgHeight
let position = 0
// 第一页已经添加
heightLeft -= pageHeight
// 当内容超过一页时
while (heightLeft >= 0) {
position = heightLeft - imgHeight
doc.addPage()
doc.addImage(imgData, 'jpeg', 0, position, imgWidth, imgHeight)
heightLeft -= pageHeight
}
// 保存PDF
doc.save('导出文档.pdf')
return 'ok'
})
.finally(() => {
loading.value = false
})
})
})
}
const exportJepg = () => {
loading.value = true
setTimeout(() => {
nextTick(() => {
html2Canvas(svgContainerRef.value, {
logging: false,
})
.then((canvas) => {
// 将canvas转换为图片
const imgData = canvas.toDataURL(`image/jpeg`, 1)
const link = document.createElement('a')
link.download = `webpage-screenshot.jpeg`
link.href = imgData
document.body.appendChild(link)
link.click()
return 'ok'
})
.finally(() => {
loading.value = false
})
})
}, 1)
}
const close = () => {
dialogVisible.value = false
}
defineExpose({ open, close })
</script>
<style lang="scss" scoped></style>