纯前端生成图片下载导出【html2canvas下载不显示的div】

用html2canvas下载div

前端有块div元素,点击“下载”按钮后,利用html2canvas把div转为canvas,再下载成格式为png的图片。

效果

page-img1
page-gif1

源码

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
<template>
<div>
<div style="margin: 30px">
<button @click="downloadPng">下载</button>
</div>
<div id="download-content" ref="pngRef">
<div>ID:{{ state.id }}</div>
<div>模型号:{{ state.model }}</div>
<div>创建者:{{ state.create_by }}</div>
<div>更新者:{{ state.update_by }}</div>
<div>描述:{{ state.details }}</div>
</div>
</div>
</template>

<script lang="ts">
import {Component, Vue} from 'vue-property-decorator'
import html2canvas from 'html2canvas'

@Component({
components: {},
filters: {},
methods: {}
})
export default class List extends Vue {
private state = {
id: '0339734AD13',
model: '42',
status: 1,
create_time: 1688449325069,
create_by: '张三',
update_by: '李四',
current_dept: '5',
details: '这是一段描述'
}
private downloadPng() {
setTimeout(() => {
// 生成图片
html2canvas((this as any).$refs.pngRef, {
backgroundColor: '#ffffff'
}).then((canvas) => {
const downloadUrl = canvas.toDataURL('image/jpeg')

// 下载图片
let aLink = document.createElement('a')
aLink.style.display = 'none'
aLink.href = downloadUrl

const file_name = 'img' + '-' + this.state.id + '.png'
aLink.download = file_name
// 触发点击-然后移除
document.body.appendChild(aLink)
aLink.click()
document.body.removeChild(aLink)
})
}, 500)
}
}
</script>

<style lang="scss" scoped>
#download-content {
margin: 30px;
border: 1px solid rgb(0, 0, 0);
text-align: left;
width: fit-content;
padding: 20px;
}
</style>

不显示div如何生成图片下载

效果

前端不希望显示div,只显示一个下载按钮。
但是canvas必须要从一个dom元素转化而来,该如何做?
利用css,前端隐藏div

1
style="position: fixed; opacity: 0"

page-img2
page-gif2

源码

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
<template>
<div>
<div style="margin: 30px">
<button @click="downloadLogo">下载</button>
</div>
<!-- 这里加上css 不显示div元素 -->
<div style="position: fixed; opacity: 0">
<div id="download-content" ref="pngRef">
<div>ID:{{ state.id }}</div>
<div>模型号:{{ state.model }}</div>
<div>创建者:{{ state.create_by }}</div>
<div>更新者:{{ state.update_by }}</div>
<div>描述:{{ state.details }}</div>
</div>
</div>
</div>
</template>

<script lang="ts">
import {Component, Vue} from 'vue-property-decorator'
import html2canvas from 'html2canvas'

@Component({
components: {},
filters: {},
methods: {}
})
export default class List extends Vue {
private state = {
id: '0339734AD13',
model: '42',
status: 1,
create_time: 1688449325069,
create_by: '张三',
update_by: '李四',
current_dept: '5',
details: '这是一段描述'
}
private downloadLogo() {
setTimeout(() => {
// 生成图片
html2canvas((this as any).$refs.pngRef, {
backgroundColor: '#ffffff'
}).then((canvas) => {
const downloadUrl = canvas.toDataURL('image/jpeg')

// 下载图片
let aLink = document.createElement('a')
aLink.style.display = 'none'
aLink.href = downloadUrl

const file_name = 'img' + '-' + this.state.id + '.png'
aLink.download = file_name
// 触发点击-然后移除
document.body.appendChild(aLink)
aLink.click()
document.body.removeChild(aLink)
})
}, 500)
}
}
</script>

<style lang="scss" scoped>
#download-content {
margin: 30px;
border: 1px solid rgb(0, 0, 0);
text-align: left;
width: fit-content;
padding: 20px;
}
</style>