предисловие
В своей предыдущей работе я столкнулся с необходимостью экспортировать Excel.Я разобрался здесь.Вообще, при экспорте excel фронтенд в основном делится на два типа.Первый -бэкенд возвращает бинарный поток данных , а другой создается непосредственно внешним интерфейсом (например, экспорт шаблона). Способ экспорта может использовать отправку формы, загрузку тега, window.open для открытия нового окна.Наиболее часто используемым должен быть тег a.
текст
Здесь в основном два способа загрузки файлов, и решение проблемы искаженных символов, когда бэкенд возвращает поток бинарных данных, и сбой сети, вызванный большим объемом данных.
Новое: добавьте чистый интерфейс для чтения данных и их анализа здесь.
Важно: здесь необходимо использовать два плагина:
import FileSaver from 'file-saver'
import XLSX from 'xlsx'
Во-первых, нам нужно получить файл для анализа, мы можем использовать компонент загрузки в element-ui (просто пример, особых ограничений нет, пока мы можем получить загруженный файл), а затем получить его файл в метод загрузки httprequest,
Затем полученный файл подставляем формальным параметром в метод парсинга и все
async uploadFile(file) {
const _file = file
const fileReader = new FileReader()
fileReader.onload = (ev) => {
try {
const data = ev.target.result
const workbook = XLSX.read(data, {
type: 'binary'
})
for (const sheet in workbook.Sheets) {
// 循环读取每个文件
const sheetArray = XLSX.utils.sheet_to_json(workbook.Sheets[sheet])
// 若当前sheet没有数据,则continue
if (sheetArray.length === 0) {
continue
}
// arr 可以是需要存放数据的数组
const arr = []
// 这里可以打印下, 可以拿到键值对形式的解析数据, 之后就可以自己去操作了
sheetArray.forEach(e => {
const rowTable = {}
for (const item in e) {
if (item === '货号') {
rowTable['productNo'] = e[item]
} else if (item === '条码') {
rowTable['barCode'] = e[item]
} else {
rowTable['safeQty'] = e[item]
}
}
arr.push(rowTable)
})
} catch (e) {
this.$message.warning('文件解析出错!')
}
}
fileReader.readAsBinaryString(_file)
},
В методе вы можете получить разобранные данные в виде пар ключ-значение, а затем оперировать ими самостоятельно. следует отметить, что при импорте объема данных, когда он слишком велик, например, 3-5 Вт, это может занять много времени, и это необходимо контролировать самостоятельно.
1. Чистый интерфейс генерирует EXcel, обновите его здесь и добавьте метод для экспорта в формат xlsx.
Этот метод мало используется, и общая загрузка файла в основном зависит от формы возвращаемого сервером потока двоичных данных.Этот метод обычно используется для шаблонов экспорта данных в формате json. Без лишних слов, давайте начнем с кода
```
let str = ''
const jsonData = [{ '仓库代码': '', '货号': '', '尺码': '', '条码': '', '切货数量': '', '折扣': '' }]
console.log(jsonData)
for (var k in jsonData[0]) {
str += k + ','
}
str = str.slice(0, str.length - 1) + '\n'
console.log(str)
// 增加\t为了不让表格显示科学计数法或者其他格式
for (let i = 0; i < jsonData.length; i++) {
for (const item in jsonData[i]) {
str += `${jsonData[i][item] + '\t'},`
}
str += '\n'
}
// encodeURIComponent解决中文乱码
const uri = 'data:application/vnd.ms-excel;charset=utf-8,\ufeff' + encodeURIComponent(str)
// 通过创建a标签实现
const link = document.createElement('a')
link.href = uri
// 对下载的文件命名
link.download = '订单模板.xls'
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
```
Экспорт xlsx-формата
Шаг 1: Установите файловую заставку и xlsx
npm i file-saver xlsx -s
第二步: 在要用的组件用中引入
import FileSaver from 'file-saver'
import XLSX from 'xlsx'
// 为表格绑定一个id, 特别注意
<el-table
id="table"
:data="tableData"
style="width: 100%">
<el-table-column
prop="date"
label="日期"
width="180">
</el-table-column>
<el-table-column
prop="name"
label="姓名"
width="180">
</el-table-column>
<el-table-column
prop="address"
label="地址">
</el-table-column>
</el-table>
Шаг 3: Привяжите метод вызова кнопки экспорта
getXlsx() {
let wb = XLSX.utils.table_to_book(document.querySelector('#table'));
/* #table 就是表格的id */
let wbout = XLSX.write(wb, {bookType: 'xlsx', bookSST: true, type: 'array'});
try {
FileSaver.saveAs(new Blob([wbout], {type: 'application/octet-stream'}), '导出数据.xlsx');
} catch (e) {
if (typeof console !== 'undefined')
console.log(e, wbout)
}
return wbout
},
2. Серверная часть возвращает поток двоичных данных для создания Excel
对于导出数据而言,返回二进制流文件是最常见的, 而前端打开链接下载excel文件一般有三种方式,
第一种是form表单方式 , 也是同步下载方式,直接下载. 这种方式的优点在于不需要对返回数据进行转换操作, 浏览器会自动同步解析. 但缺点是无法对返回结果进行操作, 如:一般工作中需要对请求进行鉴权, 这个时候,form表单方式下载是无法在请求头中带上token的, 后端只能通过从cookie中获取.
第二种是a标签下载方式, 将返回结果处理成一个新链接, 通过创建a标签打开, 这种方式的优点在于内部请求不需要对鉴权做多余处理, 也可以拿到返回结果进行操作,
缺点在于不注意之间会产生乱码,及数据量太大导致网络失败.
使用blob容器可以解决数据量大导致网络失败的问题,
而乱码问题在二进制流前拼接字符串'\ufeff'即可
```
this.$axios({
method: params.method,
url: params.url,
data: params.data,
responseType: 'blob' // 指明返回格式, 这里注明一下, 如果导出EXCEL为[object blob]的话, 可以把这段responseType:'blob' 注释掉试一下.
}).then(res => {
console.log(res) // 返回结果
// 这里尤其需要注意, '\ufeff' 用于解决乱码问题, blob可以解决数据量大导致网络失败.
const blob = new Blob(['\ufeff' + res.data], { type: 'text/csv;charset=utf-8' })
const url = window.URL.createObjectURL(blob)
// 通过创建a标签实现
const link = document.createElement('a')
link.href = url
// 对下载的文件命名, 如果后端返回名称出现乱码, 需要后端编码一下.
link.download = decodeURI(res.headers['content-disposition'].split('=')[1]) || '发货单导出数据表.csv'
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
})
```
Эпилог
Функция не сложная, следует отметить, что преобразование бинарного потока, и проблема в том, что адрес метки слишком длинный и сеть не работает.