Appearance
上传excel文件并解析图片
背景
某科技公司内测试「小美」日常需要将甲方统计的系统Bug Excel文件同步至织信系统内,Excel中包含描述、记录时间、截图。
实现步骤
我们现在可以通过以下方式实现该功能:
- 开始之前先在应用设计中创建「数据表」与「网站和资源托管模块」
- 在新建的「网站和资源托管模块」中上传excel模板
- 复制预览地址+资源文件名称
- 首先打开数据表应用设计「数据表 >> 工具栏 >> 添加控件」
- 控件内执行操作选择调用自动化
- 在自动化中定义上传文件
- 设定只接受Excel格式
- 设置Excel模板链接
- 使用脚本读取Excel内容
读取Excel并存储到数据表
javascript
/**
* 获取excel
* @param filePath 文件路径
* @returns {*[]}
*/
const getExcelRowDataList = (filePath) => {
const workbook = informat.excel.openExistFile(filePath);
const rowDataList = [];
// 默认读取第一页Sheet
const sheet = workbook.getSheetAt(0);
//返回所有的单元格数据
const firstRowNum = sheet.getFirstRowNum();
for (let rowIndex = firstRowNum; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
const rowData = [];
const row = sheet.getRow(rowIndex);
for (let colIndex = row.getFirstCellNum(); colIndex < row.getLastCellNum(); colIndex++) {
let value = null;
const cell = row.getCell(colIndex);
if (cell) {
// 获取到cell的内容
value = cell.getValue();
}
rowData.push(value);
}
rowDataList.push(rowData);
}
const excelPictureMap = new Map();
/**
* sheet.getPictures() 该方法可以获取到所有的图片
* 读取图片后,可通过picture的save(localPath),saveStorage(path),saveAttachment(tableKey,fieldKey,fieldName)
* 可以将文件内容存储到本地沙盒或者是共享存储中
*/
sheet.getPictures().forEach(picture => {
const row = picture.getRow();
const column = picture.getColumn();
let integerExcelPictureMap;
if (!excelPictureMap.has(row)) {
integerExcelPictureMap = new Map();
excelPictureMap.set(row, integerExcelPictureMap);
} else {
integerExcelPictureMap = excelPictureMap.get(row);
}
let pictureList = integerExcelPictureMap.get(column);
if (!pictureList) {
pictureList = [];
integerExcelPictureMap.set(column, pictureList);
}
pictureList.push(picture);
});
excelPictureMap.forEach((rowMap, row) => {
// 不能大于最大行
if (row > rowDataList.length - 1) {
return;
}
const colList = rowDataList[row];
rowMap.forEach((col, colIdx) => {
if (colIdx > colList.length - 1) {
return;
}
colList.splice(colIdx, 1, col)
});
});
return rowDataList;
}
/**
* 通过拿到的所有行列 根据映射关系返回对象数组
* @param filePath 文件路径
* @param mappings 数据列key映射关系
* @param dataStartIdx 开始索引
* @returns {*[]|*}
*/
const parseExcelRowDataList = (filePath, mappings, dataStartIdx) => {
// 默认第二行开始
if (undefined === dataStartIdx || null === dataStartIdx) {
dataStartIdx = 1;
}
if (!filePath || !mappings ) {
return [];
}
const excelRowDatList = getExcelRowDataList(filePath);
if (0 === excelRowDatList.length) {
return excelRowDatList;
}
const rowList = [];
for (let i = dataStartIdx; i < excelRowDatList.length; i++) {
const row = excelRowDatList[i];
const data = {};
for (let mappingsKey in mappings) {
const name = mappings[mappingsKey];
data[name] = row[mappingsKey];
}
rowList.push(data);
}
return rowList;
}
// 获取到【上传文件】步骤返回的文件列表
const fileList = automatic.getVar('fileList');
// 获取到文件Id
const fileId = fileList[0].id;
// 将文件下载到本地存储
informat.storage.download('automatic/' + fileId, fileId);
// 定义每一列映射的标识符
const fieldNameMappings = {
0: 'module_name', // 模块名称
1: 'priority', // 优先级
2: 'expected_performance_date', // 期望完成日期
3: 'photos', // 图片
4: 'remark', // 备注
}
// 本地路径
const filePath = fileId;
/**
* 通过映射拿到所有的行列
*/
const rowDataList = parseExcelRowDataList(filePath, fieldNameMappings, 1);
// 上传所有的图片
rowDataList.forEach(row => {
const photos = row.photos;
if (photos) {
const attachmentList = [];
for (let i = 0; i < photos.length; i++) {
const photo = photos[i];
const attachment = photo.saveAttachment('tab', 'photos', '图片' + i + '.png');
attachmentList.push(attachment);
}
row.photos = attachmentList;
}
informat.table.insert('tab', row);
});
效果
- 导入以下Excel
- 最终导入结果