/**
* Author: crazystudent13
* Date: 2022-10-17 09:27:05
* LastEditTime: 2022-10-17 09:32:25
* desc: 整合目前的图片,文件相关的公用方法,整合了之前的方法,目前正在重写中,暂不发布
* doc: 文章链接
*/
/**
* 获取文件后缀名
* @constructor
* @author crazystudent13
* @todo 暂无待办
* @param { file } filename - 全部文件名,包括文件的后缀名
* @return 文件后缀名
*/
export function getFileType(filename) {
var startIndex = filename.lastIndexOf('.')
if (startIndex != -1) return filename.substring(startIndex + 1, filename.length).toLowerCase()
else return ''
}
/**
* 压缩图片,前端制作缩略图,可以避免开发者自己去压缩图片
* @constructor
* @author crazystudent13
* @todo 暂无待办
* @param { file } dataURI - 需要转换为文件的base64位码
* @param { string } type - 文件类型
* @return 转换后的Base64位码
*/
export function compressImg(img) {
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
// 瓦片canvas
const tCanvas = document.createElement('canvas')
const tctx = tCanvas.getContext('2d')
const initSize = img.src.length
let width = img.width
let height = img.height
// 如果图片大于四百万像素,计算压缩比并将大小压至400万以下
let ratio
if ((ratio = (width * height) / 4000000) > 1) {
console.log('大于400万像素')
ratio = Math.sqrt(ratio)
width /= ratio
height /= ratio
} else {
ratio = 1
}
canvas.width = width
canvas.height = height
// 铺底色
ctx.fillStyle = '#fff'
ctx.fillRect(0, 0, canvas.width, canvas.height)
// 如果图片像素大于100万则使用瓦片绘制
let count
if ((count = (width * height) / 1000000) > 1) {
console.log('超过100W像素')
count = ~~(Math.sqrt(count) + 1) // 计算要分成多少块瓦片
// 计算每块瓦片的宽和高
const nw = ~~(width / count)
const nh = ~~(height / count)
tCanvas.width = nw
tCanvas.height = nh
for (let i = 0; i < count; i++) {
for (let j = 0; j < count; j++) {
tctx.drawImage(img, i * nw * ratio, j * nh * ratio, nw * ratio, nh * ratio, 0, 0, nw, nh)
ctx.drawImage(tCanvas, i * nw, j * nh, nw, nh)
}
}
} else {
ctx.drawImage(img, 0, 0, width, height)
}
// 进行最小压缩
const ndata = canvas.toDataURL('image/jpeg', 0.1)
console.log('压缩前:' + initSize)
console.log('压缩后:' + ndata.length)
console.log('压缩率:' + ~~((100 * (initSize - ndata.length)) / initSize) + '%')
tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0
return ndata
}
/**
* Base64转换为文件
* @constructor
* @author crazystudent13
* @todo 暂无待办
* @param { file } dataURI - 需要转换为文件的base64位码
* @param { string } type - 文件类型
* @return 转换后的Base64位码
*/
export function base64ToFile(dataURI, type) {
let binary = atob(dataURI.split(',')[1])
let array = []
for (let i = 0; i < binary.length; i++) {
array.push(binary.charCodeAt(i))
}
return new Blob([new Uint8Array(array)], { type: type })
}
/**
* 图片转换为Base64位码
* @constructor
* @author crazystudent13
* @todo 图片和文件
* @param { file } img - 需要转码的文件
* @return 转换后的Base64位码
*/
export function fileToBase64(img) {
var canvas = document.createElement('canvas')
canvas.width = img.width
canvas.height = img.height
var ctx = canvas.getContext('2d')
ctx.drawImage(img, 0, 0, img.width, img.height)
var ext = img.src.substring(img.src.lastIndexOf('.') + 1).toLowerCase()
var dataURL = canvas.toDataURL('image/' + ext)
return dataURL
}
/**
* 判断文件及文件大小
* @constructor
* @author crazystudent13
* @todo 这里是将文件的大小和类型一起判断了,功能有些耦合,建议将这两种方法拆开
* @param { string } file - 上传文件的名称(包含文件名)
* @param { array } typeArr - 要限制的类型,
* @param { number } size - 文件大小
* @return 字符串分割结果
*/
export function judgeUploadFile(file, typeArr, size) {
let FileExt = file.name.replace(/.+\./, '')
let TypeArrList = typeArr
let TypeArrStr = ''
let fileSize = size
TypeArrList.map((item, index, arr) => {
TypeArrStr = arr.length - 1 !== index ? TypeArrStr + item + ',' : TypeArrStr + item
})
if (TypeArrList.indexOf(FileExt.toLowerCase()) === -1) {
Message({ message: '您上传的文件格式有误', type: 'warning' })
return false
} else {
this.isLt2k = file.size / 1024 < fileSize ? '1' : '0'
if (this.isLt2k === '0') {
Message({ message: `上传文件大小不能超过${fileSize / 1024}M!`, type: 'error' })
}
return this.isLt2k === '1' ? true : false
}
}
/**
* 下载excel文件
* @constructor
* @author crazystudent13
* @todo 这个方法暂时还不稳定,建议后期多做测试
* @param { blob } blob - 需要下载的excel文件
* @param { string } fileName - 自定义文件名称
* @return 字符串分割结果
*/
export function downloadExcelFile(blob, fileName) {
// 对于<a>标签,只有 Firefox 和 Chrome(内核) 支持 download 属性
// IE10以上支持blob但是依然不支持download
if ('download' in document.createElement('a')) {
// 支持a标签download的浏览器
const link = document.createElement('a')
link.download = fileName
link.style.display = 'none'
link.href = URL.createObjectURL(blob)
document.body.appendChild(link)
link.click()
URL.revokeObjectURL(link.href)
document.body.removeChild(link)
} else {
// 其他浏览器
navigator.msSaveBlob(blob, fileName)
}
}
/**
* 自定义导出excel文件
* @constructor
* @author crazystudent13
* @todo 这个方法和downloadExcelFile 类似,要考虑合并
* @param { blob } blob - 需要下载的excel文件
* @param { string } fileName - 自定义文件名称
* @return 字符串分割结果
*/
export function exportExcelFile(data, tableLabel, fileName) {
let str = ''
// 拼接表头
tableLabel.forEach((item) => {
str += item.describe + ','
})
str += '\n'
// 拼接表格数据
data.forEach((element) => {
tableLabel.forEach((item) => {
str += element[item.name] + ','
})
str += '\n'
})
// 解决中文乱码问题
let blob = new Blob([str], { type: 'text/plain;charset=utf-8' })
blob = new Blob([String.fromCharCode(0xfeff), blob], { type: blob.type })
let object_url = window.URL.createObjectURL(blob)
let link = document.createElement('a')
link.href = object_url
link.download = fileName ? fileName + '.xls' : `file_${new Date().getTime()}` + '.xls'
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
}