记录:VUE中把HTML内容转换为图片,调用客户端文件系统存储图片到本地(可选存储位置,仅支持最新浏览器chrome,edge,火狐没有测试)

index.vue

<template>
    <div class="el-content">
		<el-button type="primary" @click="save">保存</el-button>
		<el-table  
			ref="multipleTable"
			:data="dataList"
			:span-method="arraySpanMethod"
			:show-header="true"
			empty-text="暂无数据"
			size="mini"
			class="result"
		>
			<el-table-column prop="name" label="参数" align="center" />    
			<el-table-column prop="value" label="测量值" min-width="70" align="center" />
			<el-table-column prop="min" label="最小目标值" align="center" />
			<el-table-column prop="max" label="最大目标值" align="center" />
			<el-table-column prop="status" label="状态" min-width="50" align="center" />
		</el-table>
    </div>
</template>
  
<script>
    import html2canvas from "html2canvas";;
    import Mixins from '@/mixins'
    export default {
        components: { },
        mixins: [Mixins],
        data() {
            return {
				dataList: [
					{name: 'Section 1', value: '238.00', min: '225.00', max: '260.00', status: 'V'},
					{name: 'Section 2', value: '238.00', min: '225.00', max: '260.00', status: 'V'},
					{name: 'Section 3', value: '238.00', min: '225.00', max: '260.00', status: 'V'},
					{name: 'Section 4', value: '238.00', min: '225.00', max: '260.00', status: 'V'},
					{name: 'Section 5', value: '238.00', min: '225.00', max: '260.00', status: 'V'},
					{name: 'Section 6', value: '238.00', min: '225.00', max: '260.00', status: 'V'},
					{name: 'Section 7', value: '238.00', min: '225.00', max: '260.00', status: 'V'}
				]
            }
        },
        created() {},
        mounted() {},
        beforeDestroy() {},
        methods: {
            // 保存结果-webview通信
            save() {
                html2canvas(this.$refs.multipleTable.$el).then((canvas) => {
                    let dataURL = canvas.toDataURL("image/png");
                    console.log(dataURL ); // 生成base64图片
                    this.saveFile(dataURL);
                })
            },
			// 表格合并列
            arraySpanMethod({ row, column, rowIndex, columnIndex }) {
                if (rowIndex === this.outputResults.length - 1 && columnIndex >= 1 && columnIndex <= 4) {
                    if (columnIndex === 1) {
                        return [1, 4];
                    } else {
                        return [0, 0];
                    }
                }
            },

        }
    }
</script>
  
<style lang="scss" scoped>
    @import '~@/styles/variables.scss';
    .el-content {
        display: flex;
        width: 100%;
        height: 100%;
    }
	.result.el-table {
        border: 1px solid #dfe6ec;
        font-size: $font-size-12;
        color: $black !important;
        &::before {
            content: none;
        }
        ::v-deep thead {
            color: $black !important;
        }
        th, td {
            font-size: $font-size;
        }
        ::v-deep th.el-table__cell,
        ::v-deep td.el-table__cell {
            border-bottom: solid 1px transparent !important;
        }
        ::v-deep .el-table__body-wrapper {
            .el-table__cell {
                padding: 2px 0 !important;
            }
            .el-table__row:last-child {
                td:first-child {
                    font-weight: bold;
                }
                td.el-table__cell:last-child {
                    padding-left: 10px !important;
                    text-align: left;
                }
            }
        }
        ::v-deep .cell {
            padding: 0 !important;
            white-space: nowrap !important;
        }
    }
</style>

mixins.js

let mixin = {
    data () {
        return {}
    },
    created() {},
    methods: {
        /**
         * 将base64转为Blob对象
         * @param base64Data
         * @param contentType
         */
        base64ToBlob(base64Data, contentType){
            contentType = contentType || '';  
            let sliceSize = 1024;  
            let byteCharacters = atob(base64Data.split(',')[1]);  
            let bytesLength = byteCharacters.length;  
            let slicesCount = Math.ceil(bytesLength / sliceSize);  
            let byteArrays = new Array(slicesCount);  
        
            for (let sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {  
                let begin = sliceIndex * sliceSize;  
                let end = Math.min(begin + sliceSize, bytesLength);  
                let bytes = new Array(end - begin);  
                for (let offset = begin, i = 0; offset < end; ++i, ++offset) {  
                    bytes[i] = byteCharacters[offset].charCodeAt(0);  
                }  
                byteArrays[sliceIndex] = new Uint8Array(bytes);  
            }  
            return new Blob(byteArrays, {type: contentType});
        },
        /**
         * 保存文件到本地 (只适合最新版本浏览器,chrome,edge,火狐没有测试)
         * @param base64
         */
        async saveFile(base64) {
            try {
                const opts = {
                types: [
                    {
                        description: '文件',
                        accept: {
                            // 'text/plain': ['.txt'],
                            // 'application/pdf': ['.pdf'],
                            // 'image/jpeg': ['.jpg', '.jpeg'],
                            // 'image/png': ['.png']
                            'image/jpg': ['.jpg', '.jpeg'],
                        },
                    }
                ],
                    excludeAcceptAllOption: true
                };
                const handle = await window.showSaveFilePicker(opts); // 打开保存文件对话框
                const writable = await handle.createWritable(); // 创建可写入的文件对象
                const image = this.base64ToBlob(base64, 'image/jpeg');
                // 在这里写入文件内容
                await writable.write(image);
                await writable.close();
                this.$message.success("保存成功");
            } catch (error) {
                this.$message.error("保存失败");
            }
        },
        
    }
} 
export default mixin

如果你想将接收到的数据存储到本地,以便在用户关闭浏览器后依然可以使用该数据,可以使用浏览器提供的 `localStorage` 或 `sessionStorage` 对象来实现。 `localStorage` 和 `sessionStorage` 都可以用来存储字符串类型的数据,但二者的区别在于: - `localStorage` 存储的数据没有过期时间,除非用户手动清除,否则数据将一直保存在浏览器; - `sessionStorage` 存储的数据在当前会话(即浏览器窗口或标签页)关闭前有效,关闭后数据将被清除。 下面是一个将接收到的数据存储到 `localStorage` 的示例代码: ``` mounted() { // 假设从后端接收到的数据为 data localStorage.setItem('receivedData', JSON.stringify(data)) } ``` 在上面的代码,我们使用 `localStorage` 的 `setItem` 方法将接收到的数据存储到名为 `receivedData` 的键。需要注意的是,`localStorage` 只能存储字符串类型的数据,因此我们需要使用 `JSON.stringify` 将数据转换为字符串类型。 在需要使用这个数据时,我们可以使用 `localStorage` 的 `getItem` 方法获取数据,并使用 `JSON.parse` 将字符串类型的数据解析为对象: ``` created() { const receivedData = localStorage.getItem('receivedData') if (receivedData) { this.receivedData = JSON.parse(receivedData) } } ``` 在上面的代码,我们首先使用 `localStorage` 的 `getItem` 方法获取名为 `receivedData` 的键对应的值,如果值存在,则使用 `JSON.parse` 将字符串类型的数据解析为对象,并存储Vue 实例的 `receivedData` 属性。 需要注意的是,由于 `localStorage` 存储的数据限于当前域名下的页面可以访问,因此如果你需要在多个域名下使用同一个数据,可以考虑使用第三方库或服务来实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值