我们经常会遇到读写文件的需求,这里稍微总结一下。
前端下载文件
一、下载json文件
function downloadJson(){
const data = await download();
const content = JSON.stringify(data);
const element = document.createElement('a');
const blob = new Blob([content], { type: 'text/plain;charset=utf-8' });
const objectUrl = URL.createObjectURL(blob);
element.href = objectUrl;
element.download = `aggregate_${Date.now()}.json`;
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
URL.revokeObjectURL(objectUrl);
}
二、下载excel文件
1、接口返回excel文件内容
1-1、通过get请求拿到文件内容,api请求响应类型responseType设置为blob
function download() {
return axios({
url: `your_api_url`,
method: 'get',
responseType: 'blob'
});
}
1-2、写文件
function downloadExcel(){
const result = await download();
const element = document.createElement('a');
const resType = result.headers && result.headers['content-type'] ? result.headers['content-type'] : '';
const blob = new Blob([result.data], { type: resType || 'application/vnd.ms-excel;charset=utf-8' });
const objectUrl = URL.createObjectURL(blob);
element.href = objectUrl
element.download = `download_${Date.now()}.xlsx`;
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
URL.revokeObjectURL(objectUrl);
}
2、接口返回数组
安装xlsx依赖包
npm install xlsx
// 字符串转字符流
function s2ab(s) {
const buf = new ArrayBuffer(s.length);
const view = new Uint8Array(buf);
for (let i = 0; i !== s.length; ++i) view[i] = s.charCodeAt(i) & 0xff;
return buf;
}
/**
* 将 js 对象的数组转换为工作表。
* @param {string[]} header - 表头
* @param {Object} headerDisplay - 表头名称
* @param {object[]} sheetData - 表数据
* @param {Boolean} skipHeader - 是否隐藏表头
* @returns 工作表
*/
function jsonToSheet(header, headerDisplay, sheetData, skipHeader) {
const newSheetData = skipHeader ? [headerDisplay, ...sheetData] : sheetData;
const ws = window.XLSX.utils.json_to_sheet(newSheetData, {
header,
skipHeader,
});
return ws;
}
/**
* 自定义将js数据导出下载excel
*
* sheetHeaderDisplay(表头名称) 不存在时,默认使用 sheetHeader(表头key) 当做表头名称
* @param {Object[]} data - 所有表信息
* @param {string} data[].sheetName - 表名称
* @param {string[]} data[].sheetHeader - 表头key
* @param {Object} data[].sheetHeaderDisplay - 表头名称
* @param {Object[]} data[].sheet - 表数据
* @param {string} excelName - 导出的excel名称
* @example
[
{
sheetName: 'Tom and Jerry',
sheetHeader: ['name', 'age', 'sex'],
sheetHeaderDisplay: {name: '名字', age: '年龄', sex: '性别'},
sheet: [
{ name: 'Tom', age: 3, sex: '男' },
{ name: 'Jerry', age: 2, sex: '女' },
{ name: 'Spike', age: 4, sex: '男' },
],
},
];
*/
function Xlsx(data, excelName) {
const tmpWB = {
SheetNames: [], // 保存的表标题
Sheets: {}, // 表数据
};
// 生成excel的配置项
data.forEach(item => {
const skipHeader =
Object.prototype.toString.call(item.sheetHeaderDisplay) === '[object Object]' && Object.keys(item.sheetHeaderDisplay).length > 0;
tmpWB.SheetNames.push(item.sheetName);
tmpWB.Sheets[item.sheetName] = Object.assign({}, jsonToSheet(item.sheetHeader, item.sheetHeaderDisplay, item.sheet, skipHeader), {});
});
// 创建二进制对象写入转换好的字节流
const tmpDown = new Blob(
[
s2ab(
// write 用来把数据写入并生成 xlsx 文件的 API
window.XLSX.write(
tmpWB,
{
// 要生成的文件类型: 'xlsx'|'xlsm'|'xlsb'
bookType: 'xlsx',
bookSST: false, // 是否生成Shared String Table,官方解释是,如果开启生成速度会下降,但在低版本IOS设备上有更好的兼容性
type: 'binary',
}, // 这里的数据是用来定义导出的格式类型
),
),
],
{
type: '',
},
);
const outFile = document.createElement('a');
const href = URL.createObjectURL(tmpDown); // 创建对象超链接
outFile.download = `${excelName || 'export'}.xlsx`; // 下载名称
outFile.style.display = 'none';
outFile.href = href; // 绑定a标签
document.body.appendChild(outFile);
outFile.click(); // 模拟点击实现下载
setTimeout(() => {
// 延时释放
URL.revokeObjectURL(tmpDown); // 用URL.revokeObjectURL()来释放这个object URL
document.body.removeChild(outFile);
}, 100);
}
export default Xlsx;
前端上传文件
一、原生js读文件
<div>
<input type="file" id="files"/>
</div>
<script>
var inputElement = document.getElementById("files");
inputElement.addEventListener("change", handleFiles, false);
function handleFiles() {
var selectedFile = document.getElementById("files").files[0];
var name = selectedFile.name;
var size = selectedFile.size;
console.log("文件名:"+name+"大小:"+size);
var reader = new FileReader();
reader.onload = function(result){
console.log("读取结果:", result);
};
reader.readAsText(selectedFile);
}
</script>
二、vue+elementui读文件
<el-upload
action="icon"
class="batch-import-area"
:show-file-list="false"
:http-request="batchImport"
:accept="'.xlsx'"
>
<el-button size="small" type="primary" @click="downloadExcel">批量导入</el-button>
</el-upload>
三、上传文件内容
使用axios上传
import axios from 'axios';
export const service = axios.create({
baseURL: process.env.BASE_API, // api 的 base_url
withCredentials: true,
timeout: 5000
})
export default service;
服务层
import request from '@/request'
const batchImportFile = (data, config) => {
const options = Object.assign({
url: 'your url path',
method: 'post',
data,
headers: {
'Content-Type': 'multipart/form-data'
}
}, config || {})
return request(options)
}
页面导入文件方法
import {batchImportFile} from '@/service'
async batchImport (file) {
const form = new FormData()
// 上传到指定文件夹
// form.append('folder', '/upload')
form.append('file', file.file, file.file.name);
const result = await batchImportFile(form);
if (result.data.code === 200 && result.data.data) {
return toast(`批量导入成功`)
}
return toast('批量导入失败');
}