Blob(binary large object)是计算机界通用术语之一,表示二进制大对象。在JavaScript中,Blob通常表示二进制数据,不过,它们不一定非得是大量数据,Blob也可以表示一个小型文本文件的内容。
1、将Echarts图表保存至AnyShare:
async handleSaveChart(data) {
try {
const docid = data;
function dataURLtoBlob(dataurl) {
var arr = dataurl.split(","),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], { type: mime });
}
var base64Data = thisChart.getDataURL({ type: "png" });
let blobData = dataURLtoBlob(base64Data);
// console.log("data");
// console.log(data);
const _this = this;
// 开始上传文件协议
const osbeginuploadRes = await this.$axios({
method: "post",
url: `/api/v1/file?method=osbeginupload&tokenid=${this.oauth2_token}`,
headers: {
authorization: "Bearer " + _this.oauth2_token,
},
data: {
client_mtime: new Date().getTime(),
docid,
length: blobData.size,
name: getNow() + "-折线图.png",
usehttps: false,
},
});
console.log("osbeginuploadRes");
console.log(osbeginuploadRes);
//
const authrequest = osbeginuploadRes.data.authrequest;
const header = {};
for (let i = 2; i < authrequest.length - 1; i++) {
const index = authrequest[i].indexOf(":");
header[authrequest[i].substring(0, index)] = authrequest[i]
.substring(1 + index)
.trim();
}
console.log("header");
console.log(header);
// 2、客户端自行发送上传
const uploadRes = await this.$axios({
method: authrequest[0],
url: authrequest[1],
headers: header,
// data: fileObj, // 发送文件内容
data: blobData,
});
console.log("uploadRes");
console.log(uploadRes);
// 3 上传文件完成协议
const osenduploadRes = await this.$axios({
method: "post",
url: `/api/v1/file?method=osendupload&tokenid=${this.oauth2_token}`,
headers: {
authorization: "Bearer " + this.oauth2_token,
},
data: {
docid: osbeginuploadRes.data.docid,
rev: osbeginuploadRes.data.rev,
},
});
console.log("osenduploadRes");
console.log(osenduploadRes);
this.$message({
message: "图表保存成功,请去Anyshare相关目录查看。",
type: "success",
showClose: true,
});
} catch (error) {
this.$message({
message: JSON.stringify(error),
type: "error",
showClose: true,
});
}
}
2、将下载的文件流保存至新的系统:
const _this = this;
fetch(authrequest[1], {
method: authrequest[0],
headers: header,
})
.then((res) => res.blob())
.then((res) => {
const blob = new File(
[res],
this.$microWidgetProps.contextMenu.getSelections[0].name,
{
type:
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
}
);
const formData = new FormData();
formData.append(
"FileData",
blob,
this.$microWidgetProps.contextMenu.getSelections[0].name
);
const request = new XMLHttpRequest();
request.open(
"POST",
`https://192.168.124.91:18443/webroot/decision/v10/attach/upload?width=32&height=32&filename=${encodeURIComponent(
this.$microWidgetProps.contextMenu.getSelections[0].name
)}`
);
request.setRequestHeader(
"authorization",
"Bearer " + localStorage["accessToken"]
);
request.send(formData);
request.onreadystatechange = function () {
if (request.readyState == 4 && request.status == 200) {
try {
const attachId = JSON.parse(request.responseText).attach_id;
_this.addStructure(attachId);
} catch (error) {
_this.$microWidgetProps.components.toast.error(
"FineBI仅支持单独登录,请退出FineBI账号后重试。"
);
}
}
};
});
} catch (error) {
this.$microWidgetProps.components.toast.error(error.message);
}
3、将Canvas图片保存:
<template>
<div id="meQrcode">
<div class="qrcode_box" id="qrcode_box">
<img
class="qrcode_canvas"
id="qrcode_canvas"
ref="qrcode_canvas"
alt="二维码本图"
/>
<!-- <img
v-if="qrLogo"
class="qrcode_logo"
ref="qrcode_logo"
:src="qrLogo"
alt="公司logo"
/> -->
<canvas
:width="qrSize"
:height="qrSize"
class="canvas"
ref="canvas"
></canvas>
</div>
<div class="saveButtonContainer">
<el-button
type="primary"
@click="savePic"
size="mini"
icon="el-icon-download"
>点击下载此二维码</el-button
>
<p style="margin-top: 5px">
如果二维码未出现,请先在右键菜单中点击“复制文档路径”菜单1-2次,然后再点击当前菜单。
</p>
</div>
</div>
</template>
<script>
import QRCode from "qrcode";
// import logo from "./assets/logo.png";
export default {
// props: {
// qrUrl: {
// type: String,
// default: "https://ecm.crb.cn",
// },
// qrText: {
// default: "AnyShare",
// },
// qrLogo: {
// type: String,
// default: logo,
// },
// qrLogoSize: {
// type: Number,
// default: 40,
// },
// qrSize: {
// type: Number,
// default: 300,
// },
// qrTextSize: {
// type: Number,
// default: 14,
// },
// },
data() {
return {
qrUrl: "",
qrText: "",
// qrLogo: logo,
qrLogoSize: 40,
qrSize: 300,
qrTextSize: 14,
};
},
methods: {
/**
* @argument qrUrl 二维码内容
* @argument qrSize 二维码大小
* @argument qrText 二维码中间显示文字
* @argument qrTextSize 二维码中间显示文字大小(默认16px)
* @argument qrLogo 二维码中间显示图片
* @argument qrLogoSize 二维码中间显示图片大小(默认为80)
*/
async handleQrcodeToDataUrl(qrcode) {
this.qrText = this.$microWidgetProps.contextMenu.getSelections[0].name;
const gns = this.$microWidgetProps.contextMenu.getSelections[0].docid;
const token = this.$microWidgetProps.token.getToken.access_token;
const thisInstance = this.$axios.create({
// baseURL: `${
// window.location.protocol + "//" + window.location.hostname
// }`,
baseURL: `https://ecm.crb.cn`,
headers: {
Authorization: `Bearer ${token}`,
},
});
const namepath = await thisInstance.post(
"/api/efast/v1/file/convertpath",
{
docid: gns,
}
);
const getinfobypath0 = await thisInstance.post(
"/api/efast/v1/file/getinfobypath",
{
namepath: namepath.data.namepath,
}
);
await thisInstance.get(
"/api/shared-link/v1/document/file/" +
encodeURIComponent(getinfobypath0.data.docid) +
"?type=realname"
);
const getinfobypath = await thisInstance.post(
"/api/efast/v1/file/getinfobypath",
{
namepath: namepath.data.namepath,
}
);
const getId = await thisInstance.get(
"/api/shared-link/v1/document/file/" +
encodeURIComponent(getinfobypath.data.docid) +
"?type=realname"
);
console.log("getId");
console.log(getId);
const rev = getId.data[0].id;
console.log(qrcode);
let qrcode_canvas = this.$refs.qrcode_canvas;
let qrcode_logo = this.$refs.qrcode_logo;
let canvas = this.$refs.canvas;
const that = this;
QRCode.toDataURL(
`https://ecm.crb.cn/link/${rev}`,
{ errorCorrectionLevel: "H" },
(err, url) => {
qrcode_canvas.src = url;
// 画二维码里的logo// 在canvas里进行拼接
let ctx = canvas.getContext("2d");
setTimeout(() => {
//获取图片
ctx.drawImage(qrcode_canvas, 0, 0, that.qrSize, that.qrSize);
if (that.qrLogo) {
//设置logo大小
//设置获取的logo将其变为圆角以及添加白色背景
ctx.fillStyle = "#fff";
ctx.beginPath();
let logoPosition = (that.qrSize - that.qrLogoSize) / 2; //logo相对于canvas居中定位
let h = that.qrLogoSize + 10; //圆角高 10为基数(logo四周白色背景为10/2)
let w = that.qrLogoSize + 10; //圆角宽
let x = logoPosition - 5;
let y = logoPosition - 5;
let r = 5; //圆角半径
ctx.moveTo(x + r, y);
ctx.arcTo(x + w, y, x + w, y + h, r);
ctx.arcTo(x + w, y + h, x, y + h, r);
ctx.arcTo(x, y + h, x, y, r);
ctx.arcTo(x, y, x + w, y, r);
ctx.closePath();
ctx.fill();
qrcode_logo.onload = function () {
105;
ctx.drawImage(
qrcode_logo,
logoPosition,
logoPosition,
that.qrLogoSize,
that.qrLogoSize
);
};
}
if (that.qrText) {
//设置字体
// let fpadd = 10; //规定内间距
ctx.font = "bold " + that.qrTextSize + "px Arial";
let tw = ctx.measureText(that.qrText).width; //文字真实宽度
let ftop = that.qrSize - that.qrTextSize; //根据字体大小计算文字top
let fleft = (that.qrSize - tw) / 2; //根据字体大小计算文字left
let tp = that.qrTextSize / 2; //字体边距为字体大小的一半可以自己设置
ctx.fillStyle = "#fff";
ctx.fillRect(
fleft - tp / 2,
ftop - tp / 2,
tw + tp,
that.qrTextSize + tp
);
ctx.textBaseline = "top"; //设置绘制文本时的文本基线。
ctx.fillStyle = "#333";
ctx.fillText(that.qrText, fleft, ftop);
}
qrcode_canvas.src = canvas.toDataURL();
}, 0);
}
);
},
savePic() {
let qrCodeCanvas = document
.getElementById("qrcode_box")
.getElementsByTagName("canvas");
let a = document.createElement("a");
a.href = qrCodeCanvas[0].toDataURL("image/url");
a.download = `【${this.$microWidgetProps.contextMenu.getSelections[0].name}】二维码.png`;
a.click();
},
},
mounted() {
this.$microWidgetProps.dialog.setMicroWidgetDialogTitle({
functionid: this.$microWidgetProps.config.systemInfo.functionid,
title: "扫描二维码",
});
this.handleQrcodeToDataUrl();
},
updated() {
this.handleQrcodeToDataUrl();
},
};
</script>
<style scoped>
.qrcode_box,
#meQrcode {
display: inline-block;
}
.qrcode_box img {
display: none;
}
.saveButtonContainer {
padding-top: 10px;
padding-left: 30px;
padding-right: 30px;
padding-bottom: 10px;
}
.el-button {
background: #126ee3 !important;
border: 1px solid #126ee3 !important;
height: 30px !important;
width: 100%;
font-size: 14px;
}
</style>
4、将文本生成一个.txt前计算文本的长度:
const txtContent = `课程名称:${_this.ruleForm.courseName};\n讲师名:${_this.ruleForm.teacherName};\n备注:${_this.ruleForm.courseDesc};`;
const txtBlob = new Blob([txtContent], {
type: "text/plain",
});
const len = txtBlob.length;