# 前端从剪切板获取word图片
<!-- 测试剪切板 -->
<template>
<div>
<div id="preview"></div>
</div>
</template>
<script>
let that;
import { EMFJS, RTFJS, WMFJS } from "rtf.js";
RTFJS.loggingEnabled(false);
WMFJS.loggingEnabled(false);
EMFJS.loggingEnabled(false);
export default {
components: {},
data() {
return {};
},
computed: {},
watch: {},
methods: {
stringToArrayBuffer(string) {
const buffer = new ArrayBuffer(string.length);
const bufferView = new Uint8Array(buffer);
for (let i = 0; i < string.length; i++) {
bufferView[i] = string.charCodeAt(i);
}
return buffer;
},
findAllImageElementsWithLocalSource() {
let imgs = document.querySelectorAll("#preview img");
return imgs;
},
extractImageDataFromRtf(rtfData) {
if (!rtfData) {
return [];
}
const regexPictureHeader =
/{\\pict[\s\S]+?({\\\*\\blipuid\s?[\da-fA-F]+)[\s}]*/;
const regexPicture = new RegExp(
"(?:(" + regexPictureHeader.source + "))([\\da-fA-F\\s]+)\\}",
"g"
);
// 从rtf文件中匹配出图片
const images = rtfData
.match(regexPicture)
.filter((item, index) => index % 2 === 1);
console.log(images, "images");
images.forEach((imgRtf) => {
const doc = new RTFJS.Document(that.stringToArrayBuffer(imgRtf));
doc.render().then(function (htmlElements) {
const previewDom = document.querySelector("#preview");
console.log(
htmlElements,
"htmlElements",
htmlElements[0],
previewDom
);
previewDom.appendChild(htmlElements[0]);
});
});
const result = [];
if (images) {
for (const image of images) {
let imageType = false;
// 找到支持的图片格式(这里我只拿出了png和jpeg)
if (image.includes("\\pngblip")) {
imageType = "image/png";
} else if (image.includes("\\jpegblip")) {
imageType = "image/jpeg";
}
if (imageType) {
result.push({
hex: image
.replace(regexPictureHeader, "")
.replace(/[^\da-fA-F]/g, ""),
type: imageType,
});
}
}
}
console.log(result, "result");
return result;
},
_convertHexToBase64(hexString) {
return btoa(
hexString
.match(/\w{2}/g)
.map((char) => {
return String.fromCharCode(parseInt(char, 16));
})
.join("")
);
},
replaceImagesFileSourceWithInlineRepresentation(
imageElements,
imagesHexSources,
writer
) {
console.log(imagesHexSources, "imagesHexSources");
if (imageElements.length === imagesHexSources.length) {
for (let i = 0; i < imageElements.length; i++) {
const newSrc = `data:${
imagesHexSources[i].type
};base64,${this._convertHexToBase64(imagesHexSources[i].hex)}`;
imageElements[i].setAttribute("src", newSrc);
}
}
},
},
created() {
that = this;
},
mounted() {
window.addEventListener("paste", function (e) {
const clipdata = e.clipboardData || window.clipboardData;
// document.querySelector("#preview").innerHTML =
// clipdata.getData("text/html");
let rtf = clipdata.getData("text/rtf");
let imgs = that.findAllImageElementsWithLocalSource();
console.log(rtf, "rtf", imgs);
that.replaceImagesFileSourceWithInlineRepresentation(
imgs,
that.extractImageDataFromRtf(rtf)
);
});
},
};
</script>
<style lang="css" scoped></style>
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
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