vue3-components-plus 3.0.25 → 3.0.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ComponentDemo/PdfDemo copy.vue +234 -0
- package/dist/ComponentDemo/PdfDemo.vue +35 -8
- package/dist/ComponentDemo/pdfReade copy.vue +369 -0
- package/dist/ComponentDemo/pdfReade.vue +590 -0
- package/dist/vue3-components-plus.css +1 -1
- package/dist/vue3-components-plus.js +128 -55
- package/dist/vue3-components-plus.umd.cjs +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,590 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="pdf-reader-page">
|
|
3
|
+
<div class="toolbar">
|
|
4
|
+
<div class="file-info">
|
|
5
|
+
<strong>{{ fileTitle }}</strong>
|
|
6
|
+
<span>{{ statusText }}</span>
|
|
7
|
+
</div>
|
|
8
|
+
<button type="button" :disabled="isPrintDisabled" @click="printPdf">
|
|
9
|
+
{{ isPrinting ? '等待渲染...' : '打印 PDF 区域' }}
|
|
10
|
+
</button>
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
<div ref="pdfWrapperRef" class="pdf-wrapper">
|
|
14
|
+
<div v-for="pdf in pdfFiles" :key="pdf.id" class="pdf-item">
|
|
15
|
+
<div class="pdf-item-header">
|
|
16
|
+
<strong>{{ pdf.name }}</strong>
|
|
17
|
+
<span>{{ getPdfStatusText(pdf) }}</span>
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
<PDF
|
|
21
|
+
v-if="pdf.data"
|
|
22
|
+
:key="pdf.viewerKey"
|
|
23
|
+
:src="pdf.data"
|
|
24
|
+
pdf-width="100%"
|
|
25
|
+
:row-gap="12"
|
|
26
|
+
:show-progress="true"
|
|
27
|
+
:show-page-tooltip="true"
|
|
28
|
+
:show-back-to-top-btn="false"
|
|
29
|
+
@onPdfInit="handlePdfInit(pdf, $event)"
|
|
30
|
+
@onProgress="handleProgress(pdf, $event)"
|
|
31
|
+
@onComplete="handleDownloadComplete(pdf)"
|
|
32
|
+
/>
|
|
33
|
+
|
|
34
|
+
<div v-else class="loading-state">
|
|
35
|
+
{{ getPdfStatusText(pdf) }}
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
</template>
|
|
41
|
+
|
|
42
|
+
<script setup lang="ts">
|
|
43
|
+
import { computed, nextTick, onBeforeMount, onMounted, ref } from 'vue'
|
|
44
|
+
import PDF from 'pdf-vue3'
|
|
45
|
+
|
|
46
|
+
interface PdfFileState {
|
|
47
|
+
id: number
|
|
48
|
+
name: string
|
|
49
|
+
url: string
|
|
50
|
+
delay: number
|
|
51
|
+
data: Uint8Array | null
|
|
52
|
+
totalPages: number
|
|
53
|
+
progress: number
|
|
54
|
+
isDownloadComplete: boolean
|
|
55
|
+
error: string
|
|
56
|
+
viewerKey: number
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const fileTitle = '多个 PDF 异步加载打印测试'
|
|
60
|
+
const pdfWrapperRef = ref<HTMLElement | null>(null)
|
|
61
|
+
const isPrinting = ref(false)
|
|
62
|
+
const pdfAssetUrl = new URL('../assets/驿云通 (11).pdf', import.meta.url).href
|
|
63
|
+
|
|
64
|
+
const pdfFiles = ref<PdfFileState[]>([
|
|
65
|
+
createPdfFile(1, '异步 PDF 1 - 驿云通 (11).pdf', 300),
|
|
66
|
+
createPdfFile(2, '异步 PDF 2 - 驿云通 (11).pdf', 1200),
|
|
67
|
+
createPdfFile(3, '异步 PDF 3 - 驿云通 (11).pdf', 2200),
|
|
68
|
+
])
|
|
69
|
+
|
|
70
|
+
const loadedPdfCount = computed(() => pdfFiles.value.filter((pdf) => pdf.data && !pdf.error).length)
|
|
71
|
+
const readyPdfCount = computed(
|
|
72
|
+
() =>
|
|
73
|
+
pdfFiles.value.filter(
|
|
74
|
+
(pdf) => pdf.data && pdf.totalPages > 0 && pdf.isDownloadComplete && !pdf.error,
|
|
75
|
+
).length,
|
|
76
|
+
)
|
|
77
|
+
const totalPages = computed(() =>
|
|
78
|
+
pdfFiles.value.reduce((pageCount, pdf) => pageCount + pdf.totalPages, 0),
|
|
79
|
+
)
|
|
80
|
+
const hasLoadError = computed(() => pdfFiles.value.some((pdf) => pdf.error))
|
|
81
|
+
const isAllPdfReady = computed(
|
|
82
|
+
() =>
|
|
83
|
+
pdfFiles.value.length > 0 &&
|
|
84
|
+
pdfFiles.value.every(
|
|
85
|
+
(pdf) => pdf.data && pdf.totalPages > 0 && pdf.isDownloadComplete && !pdf.error,
|
|
86
|
+
),
|
|
87
|
+
)
|
|
88
|
+
const isPrintDisabled = computed(() => isPrinting.value || !isAllPdfReady.value)
|
|
89
|
+
|
|
90
|
+
const statusText = computed(() => {
|
|
91
|
+
if (hasLoadError.value) {
|
|
92
|
+
return '有 PDF 加载失败,请查看单个文件状态'
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (isPrinting.value) {
|
|
96
|
+
return '正在等待全部 PDF 页面渲染完成'
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (!isAllPdfReady.value) {
|
|
100
|
+
return `异步加载中:${readyPdfCount.value}/${pdfFiles.value.length} 个 PDF 就绪`
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return `已就绪:${loadedPdfCount.value} 个 PDF,共 ${totalPages.value} 页`
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
onBeforeMount(() => {
|
|
107
|
+
resetLegacyPdfWorker()
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
onMounted(() => {
|
|
111
|
+
void loadPdfFiles()
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
function createPdfFile(id: number, name: string, delay: number): PdfFileState {
|
|
115
|
+
return {
|
|
116
|
+
id,
|
|
117
|
+
name,
|
|
118
|
+
url: pdfAssetUrl,
|
|
119
|
+
delay,
|
|
120
|
+
data: null,
|
|
121
|
+
totalPages: 0,
|
|
122
|
+
progress: 0,
|
|
123
|
+
isDownloadComplete: false,
|
|
124
|
+
error: '',
|
|
125
|
+
viewerKey: 0,
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
async function loadPdfFiles() {
|
|
130
|
+
await Promise.all(pdfFiles.value.map((pdf) => loadLocalPdf(pdf)))
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
async function loadLocalPdf(pdf: PdfFileState) {
|
|
134
|
+
pdf.error = ''
|
|
135
|
+
pdf.progress = 0
|
|
136
|
+
pdf.totalPages = 0
|
|
137
|
+
pdf.isDownloadComplete = false
|
|
138
|
+
pdf.data = null
|
|
139
|
+
|
|
140
|
+
try {
|
|
141
|
+
await sleep(pdf.delay)
|
|
142
|
+
pdf.progress = 10
|
|
143
|
+
resetLegacyPdfWorker()
|
|
144
|
+
|
|
145
|
+
const response = await fetch(pdf.url)
|
|
146
|
+
if (!response.ok) {
|
|
147
|
+
throw new Error(`HTTP ${response.status}`)
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
pdf.progress = 60
|
|
151
|
+
const buffer = await response.arrayBuffer()
|
|
152
|
+
|
|
153
|
+
resetLegacyPdfWorker()
|
|
154
|
+
pdf.viewerKey += 1
|
|
155
|
+
pdf.data = new Uint8Array(buffer)
|
|
156
|
+
pdf.progress = 100
|
|
157
|
+
} catch (error) {
|
|
158
|
+
console.error(error)
|
|
159
|
+
pdf.error = 'PDF 文件读取失败'
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function resetLegacyPdfWorker() {
|
|
164
|
+
delete (window as Window & { pdfjsWorker?: unknown }).pdfjsWorker
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function getPdfStatusText(pdf: PdfFileState) {
|
|
168
|
+
if (pdf.error) {
|
|
169
|
+
return pdf.error
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (!pdf.data) {
|
|
173
|
+
return pdf.progress > 0 ? `异步读取中 ${Math.floor(pdf.progress)}%` : '等待异步加载'
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (!pdf.totalPages) {
|
|
177
|
+
return `解析中 ${Math.floor(pdf.progress)}%`
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if (!pdf.isDownloadComplete) {
|
|
181
|
+
return `渲染中 ${Math.floor(pdf.progress)}%`
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return `${pdf.totalPages} 页,已渲染`
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function handlePdfInit(file: PdfFileState, pdf: { numPages?: number }) {
|
|
188
|
+
file.totalPages = pdf.numPages ?? 0
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function handleProgress(file: PdfFileState, progress: number) {
|
|
192
|
+
file.progress = progress
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function handleDownloadComplete(file: PdfFileState) {
|
|
196
|
+
file.isDownloadComplete = true
|
|
197
|
+
file.progress = 100
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
async function printPdf() {
|
|
201
|
+
if (isPrinting.value) return
|
|
202
|
+
|
|
203
|
+
isPrinting.value = true
|
|
204
|
+
|
|
205
|
+
try {
|
|
206
|
+
await waitForAllPagesRendered()
|
|
207
|
+
await printWrapperCanvases()
|
|
208
|
+
} catch (error) {
|
|
209
|
+
console.error(error)
|
|
210
|
+
window.alert('PDF 页面加载超时,请稍后再试')
|
|
211
|
+
} finally {
|
|
212
|
+
isPrinting.value = false
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
async function waitForAllPagesRendered(timeout = 30000) {
|
|
217
|
+
const startTime = Date.now()
|
|
218
|
+
|
|
219
|
+
while (Date.now() - startTime < timeout) {
|
|
220
|
+
await nextTick()
|
|
221
|
+
await waitFrame()
|
|
222
|
+
|
|
223
|
+
if (isAllPdfReady.value && totalPages.value > 0 && areAllCanvasesPainted()) {
|
|
224
|
+
await waitForStableLayout()
|
|
225
|
+
return
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
await sleep(100)
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
throw new Error('PDF render timeout')
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
async function waitForStableLayout() {
|
|
235
|
+
let previousHeight = -1
|
|
236
|
+
|
|
237
|
+
for (let index = 0; index < 5; index += 1) {
|
|
238
|
+
await waitFrame()
|
|
239
|
+
await sleep(80)
|
|
240
|
+
|
|
241
|
+
const currentHeight = getCanvasContainerHeight()
|
|
242
|
+
if (currentHeight > 0 && currentHeight === previousHeight) {
|
|
243
|
+
await waitFrame()
|
|
244
|
+
await waitFrame()
|
|
245
|
+
return
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
previousHeight = currentHeight
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function areAllCanvasesPainted() {
|
|
253
|
+
const canvases = getCanvases()
|
|
254
|
+
|
|
255
|
+
return (
|
|
256
|
+
canvases.length >= totalPages.value &&
|
|
257
|
+
canvases.every((canvas) => canvas.width > 0 && canvas.height > 0 && isCanvasPainted(canvas))
|
|
258
|
+
)
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
function getCanvases() {
|
|
262
|
+
return Array.from(
|
|
263
|
+
pdfWrapperRef.value?.querySelectorAll<HTMLCanvasElement>(
|
|
264
|
+
'.pdf-vue3-canvas-container canvas',
|
|
265
|
+
) ?? [],
|
|
266
|
+
)
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
async function printWrapperCanvases() {
|
|
270
|
+
const canvases = getCanvases()
|
|
271
|
+
if (!canvases.length) {
|
|
272
|
+
throw new Error('No PDF canvas found')
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
const printFrame = document.createElement('iframe')
|
|
276
|
+
printFrame.title = 'pdf-wrapper-print'
|
|
277
|
+
printFrame.style.position = 'fixed'
|
|
278
|
+
printFrame.style.right = '0'
|
|
279
|
+
printFrame.style.bottom = '0'
|
|
280
|
+
printFrame.style.width = '0'
|
|
281
|
+
printFrame.style.height = '0'
|
|
282
|
+
printFrame.style.border = '0'
|
|
283
|
+
document.body.append(printFrame)
|
|
284
|
+
|
|
285
|
+
const printDocument = printFrame.contentDocument
|
|
286
|
+
const printWindow = printFrame.contentWindow
|
|
287
|
+
if (!printDocument || !printWindow) {
|
|
288
|
+
printFrame.remove()
|
|
289
|
+
throw new Error('Print frame unavailable')
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const pages = canvases
|
|
293
|
+
.map((canvas) => canvas.toDataURL('image/png'))
|
|
294
|
+
.map((src) => `<img class="pdf-page" src="${src}" alt="" />`)
|
|
295
|
+
.join('')
|
|
296
|
+
|
|
297
|
+
printDocument.open()
|
|
298
|
+
printDocument.write(`
|
|
299
|
+
<!doctype html>
|
|
300
|
+
<html>
|
|
301
|
+
<head>
|
|
302
|
+
<meta charset="utf-8" />
|
|
303
|
+
<title>PDF Print</title>
|
|
304
|
+
<style>
|
|
305
|
+
@page {
|
|
306
|
+
margin: 0;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
html,
|
|
310
|
+
body {
|
|
311
|
+
margin: 0;
|
|
312
|
+
padding: 0;
|
|
313
|
+
background: #fff;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
.pdf-page {
|
|
317
|
+
display: block;
|
|
318
|
+
width: 100%;
|
|
319
|
+
height: auto;
|
|
320
|
+
break-after: page;
|
|
321
|
+
page-break-after: always;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
.pdf-page:last-child {
|
|
325
|
+
break-after: auto;
|
|
326
|
+
page-break-after: auto;
|
|
327
|
+
}
|
|
328
|
+
</style>
|
|
329
|
+
</head>
|
|
330
|
+
<body>${pages}</body>
|
|
331
|
+
</html>
|
|
332
|
+
`)
|
|
333
|
+
printDocument.close()
|
|
334
|
+
|
|
335
|
+
await waitForPrintFrameImages(printDocument)
|
|
336
|
+
printWindow.focus()
|
|
337
|
+
printWindow.print()
|
|
338
|
+
|
|
339
|
+
window.setTimeout(() => {
|
|
340
|
+
printFrame.remove()
|
|
341
|
+
}, 1000)
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
function waitForPrintFrameImages(printDocument: Document) {
|
|
345
|
+
const images = Array.from(printDocument.images)
|
|
346
|
+
|
|
347
|
+
return Promise.all(
|
|
348
|
+
images.map((image) => {
|
|
349
|
+
if (image.complete) {
|
|
350
|
+
return Promise.resolve()
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
return new Promise<void>((resolve, reject) => {
|
|
354
|
+
image.onload = () => resolve()
|
|
355
|
+
image.onerror = () => reject(new Error('Print image failed to load'))
|
|
356
|
+
})
|
|
357
|
+
}),
|
|
358
|
+
)
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
function getCanvasContainerHeight() {
|
|
362
|
+
return pdfWrapperRef.value?.querySelector('.pdf-vue3-canvas-container')?.scrollHeight ?? 0
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
function isCanvasPainted(canvas: HTMLCanvasElement) {
|
|
366
|
+
const context = canvas.getContext('2d')
|
|
367
|
+
if (!context) return false
|
|
368
|
+
|
|
369
|
+
const points = [
|
|
370
|
+
[0.5, 0.5],
|
|
371
|
+
[0.25, 0.25],
|
|
372
|
+
[0.75, 0.25],
|
|
373
|
+
[0.25, 0.75],
|
|
374
|
+
[0.75, 0.75],
|
|
375
|
+
]
|
|
376
|
+
|
|
377
|
+
try {
|
|
378
|
+
return points.some(([xRatio, yRatio]) => {
|
|
379
|
+
const x = Math.max(0, Math.min(canvas.width - 1, Math.floor(canvas.width * xRatio)))
|
|
380
|
+
const y = Math.max(0, Math.min(canvas.height - 1, Math.floor(canvas.height * yRatio)))
|
|
381
|
+
return context.getImageData(x, y, 1, 1).data[3] > 0
|
|
382
|
+
})
|
|
383
|
+
} catch {
|
|
384
|
+
return canvas.width > 0 && canvas.height > 0
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
function waitFrame() {
|
|
389
|
+
return new Promise<void>((resolve) => {
|
|
390
|
+
requestAnimationFrame(() => resolve())
|
|
391
|
+
})
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
function sleep(duration: number) {
|
|
395
|
+
return new Promise<void>((resolve) => {
|
|
396
|
+
window.setTimeout(resolve, duration)
|
|
397
|
+
})
|
|
398
|
+
}
|
|
399
|
+
</script>
|
|
400
|
+
|
|
401
|
+
<style scoped lang="scss">
|
|
402
|
+
.pdf-reader-page {
|
|
403
|
+
display: flex;
|
|
404
|
+
flex-direction: column;
|
|
405
|
+
height: 100%;
|
|
406
|
+
min-height: 720px;
|
|
407
|
+
background: #f3f5f8;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
.toolbar {
|
|
411
|
+
flex: none;
|
|
412
|
+
display: flex;
|
|
413
|
+
align-items: center;
|
|
414
|
+
justify-content: space-between;
|
|
415
|
+
gap: 16px;
|
|
416
|
+
padding: 14px 18px;
|
|
417
|
+
border-bottom: 1px solid #d8dee8;
|
|
418
|
+
background: #ffffff;
|
|
419
|
+
|
|
420
|
+
.file-info {
|
|
421
|
+
display: flex;
|
|
422
|
+
flex-direction: column;
|
|
423
|
+
gap: 4px;
|
|
424
|
+
min-width: 0;
|
|
425
|
+
color: #1f2937;
|
|
426
|
+
|
|
427
|
+
strong,
|
|
428
|
+
span {
|
|
429
|
+
overflow: hidden;
|
|
430
|
+
text-overflow: ellipsis;
|
|
431
|
+
white-space: nowrap;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
span {
|
|
435
|
+
color: #64748b;
|
|
436
|
+
font-size: 13px;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
button {
|
|
441
|
+
flex: none;
|
|
442
|
+
min-width: 88px;
|
|
443
|
+
height: 36px;
|
|
444
|
+
padding: 0 16px;
|
|
445
|
+
border: 1px solid #2563eb;
|
|
446
|
+
border-radius: 4px;
|
|
447
|
+
background: #2563eb;
|
|
448
|
+
color: #ffffff;
|
|
449
|
+
cursor: pointer;
|
|
450
|
+
|
|
451
|
+
&:disabled {
|
|
452
|
+
border-color: #b8c2d6;
|
|
453
|
+
background: #b8c2d6;
|
|
454
|
+
cursor: not-allowed;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
.pdf-wrapper {
|
|
460
|
+
flex: 1;
|
|
461
|
+
min-height: 0;
|
|
462
|
+
overflow: auto;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
.pdf-item {
|
|
466
|
+
background: #e9edf3;
|
|
467
|
+
|
|
468
|
+
& + & {
|
|
469
|
+
border-top: 1px solid #cbd5e1;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
.pdf-item-header {
|
|
474
|
+
position: sticky;
|
|
475
|
+
top: 0;
|
|
476
|
+
z-index: 1;
|
|
477
|
+
display: flex;
|
|
478
|
+
align-items: center;
|
|
479
|
+
justify-content: space-between;
|
|
480
|
+
gap: 16px;
|
|
481
|
+
padding: 10px 18px;
|
|
482
|
+
border-bottom: 1px solid #d8dee8;
|
|
483
|
+
background: #ffffff;
|
|
484
|
+
color: #1f2937;
|
|
485
|
+
|
|
486
|
+
strong,
|
|
487
|
+
span {
|
|
488
|
+
overflow: hidden;
|
|
489
|
+
text-overflow: ellipsis;
|
|
490
|
+
white-space: nowrap;
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
span {
|
|
494
|
+
flex: none;
|
|
495
|
+
color: #64748b;
|
|
496
|
+
font-size: 13px;
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
.loading-state {
|
|
501
|
+
display: flex;
|
|
502
|
+
align-items: center;
|
|
503
|
+
justify-content: center;
|
|
504
|
+
height: 100%;
|
|
505
|
+
min-height: 360px;
|
|
506
|
+
color: #475569;
|
|
507
|
+
font-size: 14px;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
:deep(.pdf-vue3-scroller) {
|
|
511
|
+
background: #e9edf3;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
:deep(.pdf-vue3-canvas-container) {
|
|
515
|
+
padding: 18px 0;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
@media (max-width: 768px) {
|
|
519
|
+
.pdf-reader-page {
|
|
520
|
+
min-height: 100vh;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
.toolbar {
|
|
524
|
+
align-items: stretch;
|
|
525
|
+
flex-direction: column;
|
|
526
|
+
|
|
527
|
+
button {
|
|
528
|
+
width: 100%;
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
@media print {
|
|
534
|
+
.pdf-reader-page {
|
|
535
|
+
display: block;
|
|
536
|
+
height: auto;
|
|
537
|
+
min-height: auto;
|
|
538
|
+
background: #ffffff;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
.toolbar {
|
|
542
|
+
display: none !important;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
.pdf-item {
|
|
546
|
+
background: #ffffff !important;
|
|
547
|
+
break-after: page;
|
|
548
|
+
page-break-after: always;
|
|
549
|
+
|
|
550
|
+
&:last-child {
|
|
551
|
+
break-after: auto;
|
|
552
|
+
page-break-after: auto;
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
.pdf-item-header {
|
|
557
|
+
display: none !important;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
.pdf-wrapper,
|
|
561
|
+
:deep(.pdf-vue3-main),
|
|
562
|
+
:deep(.pdf-vue3-container),
|
|
563
|
+
:deep(.pdf-vue3-scroller) {
|
|
564
|
+
height: auto !important;
|
|
565
|
+
max-height: none !important;
|
|
566
|
+
overflow: visible !important;
|
|
567
|
+
background: #ffffff !important;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
:deep(.pdf-vue3-canvas-container) {
|
|
571
|
+
width: 100% !important;
|
|
572
|
+
padding: 0 !important;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
:deep(.pdf-vue3-canvas-container canvas) {
|
|
576
|
+
width: 100% !important;
|
|
577
|
+
height: auto !important;
|
|
578
|
+
margin: 0 auto !important;
|
|
579
|
+
box-shadow: none !important;
|
|
580
|
+
break-after: page;
|
|
581
|
+
page-break-after: always;
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
:deep(.pdf-vue3-progress),
|
|
585
|
+
:deep(.pdf-vue3-pageTooltip),
|
|
586
|
+
:deep(.pdf-vue3-backToTopBtn) {
|
|
587
|
+
display: none !important;
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
</style>
|