Skip to content

上传excel文件并解析图片

背景

某科技公司内测试「小美」日常需要将甲方统计的系统Bug Excel文件同步至织信系统内,Excel中包含描述、记录时间、截图。

实现步骤

我们现在可以通过以下方式实现该功能:

  • 开始之前先在应用设计中创建「数据表」与「网站和资源托管模块」

创建表格创建网站设置

  • 在新建的「网站和资源托管模块」中上传excel模板 上传文件
  • 复制预览地址+资源文件名称 链接
  • 首先打开数据表应用设计「数据表 >> 工具栏 >> 添加控件」 添加控件
  • 控件内执行操作选择调用自动化 按钮设置
  • 在自动化中定义上传文件 在自动化中定义上传文件
  • 设定只接受Excel格式 设定只接受Excel格式
  • 设置Excel模板链接 img_6.png
  • 使用脚本读取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
    导入以下Excel
  • 最终导入结果
    最终导入结果