Vue实现pdf、doc、txt、xlsx等的预览
# docx、doc
npm i docx-preview
1
<div ref="childRef"></div>
...
import {renderAsync} from "docx-preview";
...
data() {
return {
pdfDoc: null,
}
},
methods: {
async previewDocx(url) {
let blob = await getBlob(url);
// 选择要渲染的元素
// 用docx-preview渲染
renderAsync(blob, this.$refs.childRef);
},
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
npm in pdfjs-dist@2.2.228
1
Vue2 使用最新版本有问题,详见pdfjs-dist使用上由版本导致的问题
<div class="pdf-tool-bar">
<div>{{ pdfParams.pageNumber }} / {{ pdfParams.numPages }}</div>
<el-button type="primary" :disabled="pdfParams.pageNumber == pdfParams.numPages" @click="nextPagePdf">下一页 </el-button>
<el-button type="primary" :disabled="pdfParams.pageNumber == 1" @click="prevPagePdf">上一页</el-button>
<el-button type="primary" @click="rotatePagePdf" >旋转</el-button>
<el-button type="primary" :disabled="pdfParams.scale==5" @click="toBigPdf" >放大</el-button>
<el-button type="primary" :disabled="pdfParams.scale==1" @click="toSmallPdf">缩小</el-button>
</div>
<canvas ref="refPdf"></canvas>
...
import * as PDFJS from "pdfjs-dist";
...
data() {
return {
pdfParams: {
pageNumber: 1, // 当前页
total: 0, // 总页数
scale: 1.5, // 缩放
rotate: 0 // 旋转角度
},
pdfDoc: null,
}
},
methods: {
async previewPdf(url) {
const pdfjsWorker = await import("pdfjs-dist/build/pdf.worker.entry");
PDFJS.GlobalWorkerOptions.workerSrc = pdfjsWorker;
PDFJS.getDocument(url).promise.then(pdfDoc => {
this.pdfDoc = pdfDoc;
this.pdfParams.total = pdfDoc.numPages;
this.getPdfPage(1);
});
},
getPdfPage(num) {
this.pdfDoc.getPage(num).then(page => {
// 设置canvas相关的属性
const canvas = this.$refs.refPdf;
const ctx = canvas.getContext("2d");
const dpr = window.devicePixelRatio || 1;
const bsr =
ctx.webkitBackingStorePixelRatio ||
ctx.mozBackingStorePixelRatio ||
ctx.msBackingStorePixelRatio ||
ctx.oBackingStorePixelRatio ||
ctx.backingStorePixelRatio ||
1;
const ratio = dpr / bsr;
const viewport = page.getViewport(
{
scale: this.pdfParams.scale, // 缩放
rotation: this.pdfParams.rotate // 旋转
}
);
canvas.width = viewport.width * ratio;
canvas.height = viewport.height * ratio;
canvas.style.width = viewport.width + "px";
canvas.style.height = viewport.height + "px";
ctx.setTransform(ratio, 0, 0, ratio, 0, 0);
const renderContext = {
canvasContext: ctx,
viewport: viewport
};
// 数据渲染到canvas画布上
page.render(renderContext);
});
},
// 前一页
prevPagePdf() {
if (this.pdfParams.pageNumber > 1) {
this.pdfParams.pageNumber -= 1;
} else {
this.pdfParams.pageNumber = 1;
}
// 重新渲染
this.getPdfPage(this.pdfParams.pageNumber);
},
// 下一页
nextPagePdf() {
if (this.pdfParams.pageNumber < this.pdfParams.total) {
this.pdfParams.pageNumber += 1;
} else {
this.pdfParams.pageNumber = this.pdfParams.total;
}
// 重新渲染
this.getPdfPage(this.pdfParams.pageNumber);
},
// 旋转
rotatePagePdf() {
this.pdfParams.rotate += 90;
// 重新渲染
this.getPdfPage(this.pdfParams.pageNumber);
},
// 放大
toBigPdf() {
if (this.pdfParams.scale < 5) {
this.pdfParams.scale += 0.5;
} else {
this.pdfParams.scale = 5;
}
// 重新渲染
this.getPdfPage(this.pdfParams.pageNumber);
},
// 缩小
toSmallPdf() {
if (this.pdfParams.scale > 1) {
this.pdfParams.scale -= 0.5;
} else {
this.pdfParams.scale = 1;
}
// 重新渲染
this.getPdfPage(this.pdfParams.pageNumber);
},
}
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
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
# txt
div class="txt-box">{{ txt }}</div>
...
import axios from "axios";
...
data() {
return {
txt: null,
}
},
methods: {
async previewTxt(url) {
const {data} = await axios.get(url, {
responseType: "text"
});
this.txt = data;
},
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# xls,xlsx
npm i xlsx
1
<el-table :data="excelData" style="width: 100%">
<el-table-column
v-for="(value, key, index) in excelData[0]"
:key="index"
:prop="key"
:label="key"
/>
</el-table>
...
import axios from "axios";
import * as XLSX from "xlsx/xlsx.mjs";
...
data() {
return {
excelData: [],
workbook: null,
}
},
methods: {
// 在线查看excel文件
async previewExcel(url) {
const {data} = await axios.get(url, {
responseType: "arraybuffer"
});
var file = new Uint8Array(data);
const workbook = XLSX.read(file, {type: "array"});
const sheetNames = workbook.SheetNames; // 工作表名称集合
this.workbook = workbook;
this.getTable(sheetNames[0]);
},
getTable(sheetName) {
const worksheet = this.workbook.Sheets[sheetName];
this.excelData = XLSX.utils.sheet_to_json(worksheet);
}
}
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
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
上次更新: 2024/01/18, 10:44:15