美文网首页
动态配置导入excel

动态配置导入excel

作者: King斌 | 来源:发表于2024-12-11 16:58 被阅读0次

Controller

 /**
     * 导出填报配置列表
     */
    @PostMapping("/importData")
    public R importData(@RequestPart("file") MultipartFile file, @NotNull(message = "报表ID不可为空") Integer id) throws Exception {

        try {
            // 查询表的列配置
            List<TbFieldsConfig> headers = iTbConfigService.getFieldsConfigList(id);
            // 解析excel
            TbTableDataImportListener listener = new TbTableDataImportListener(headers);
            EasyExcel.read(file.getInputStream(), listener).sheet().doRead();
            List<JSONObject> dataList = listener.getDataList();
            // 插入数据
            iTbConfigService.insertDataList(dataList, id);
        return R.ok("导入成功");
        } catch (IOException e) {
            return R.ok("导入失败:" + e.getMessage());
        }
    }

Listener

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.zhby.common.exception.ServiceException;
import com.zhby.tb.domain.TbFieldsConfig;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

@Slf4j
public class TbTableDataImportListener extends AnalysisEventListener<Map<Integer, Object>> {


    private Map<String, String> headerConfig = null;
    private Map<Integer, String> headerIndexToDbField = new LinkedHashMap<>(); // 列索引到数据库字段名的映射

    private final List<TbFieldsConfig> headers;
    private final List<JSONObject> dataList = new ArrayList<>();


    public TbTableDataImportListener( List<TbFieldsConfig> headers) {
        this.headers = headers;
    }

    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        if (null == headers || headers.size() <= 0) {
            throw new ServiceException("没有配置报表的字段配置信!!!");
        }
        // 获取表头配置
        headerConfig = new LinkedHashMap<>();
        for (Map.Entry<Integer, String> entry : headMap.entrySet()) {
            String chineseHeader = entry.getValue(); // 假设这是中文表头
            if (StrUtil.isNotBlank(chineseHeader)) { // 只保留有效的列
                String dbFieldName = getDbFieldName(chineseHeader); // 从中文表头获取数据库字段名
                if (StrUtil.isNotBlank(dbFieldName)) {
                    // 只保留有效的列
                    headerConfig.put(dbFieldName, chineseHeader);
                    headerIndexToDbField.put(entry.getKey(), dbFieldName);
                }
            }
        }
    }

    private String getDbFieldName(String chineseHeader) {
        String key = null;
        for (int i = 0; i < headers.size(); i++) {
            if (chineseHeader.equals(headers.get(i).getFieldName())) {
                key = headers.get(i).getFieldCode();
            }
        }
        return key;
    }

    @Override
    public void invoke(Map<Integer, Object> object, AnalysisContext context) {
        JSONObject row = new JSONObject();
        for (Map.Entry<Integer, String> entry : headerIndexToDbField.entrySet()) {
            Integer columnIndex = entry.getKey();
            String dbFieldName = entry.getValue();
            Object cellValue = object.get(columnIndex);
            row.put(dbFieldName, cellValue);
        }
        dataList.add(row);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {

    }

    public List<JSONObject> getDataList() {
        return dataList;
    }
}

Service

   @Transactional(rollbackFor = Exception.class)
    @Override
    public int insertDataList(List<JSONObject> datas, Integer id) {
        // 根据表名查询所有指标表的字段
        List<TbFieldsConfig> fields = getFieldsConfigList(id);
        List<Map> dataMaps = new ArrayList<>(); 
        //把数据转换成code的map
格式
        datas.forEach(data -> {
            Map<String, Object> dataMap = new HashMap<>();
            for (TbFieldsConfig field : fields) {
                dataMap.put( field.getFieldCode(), data.get(field.getFieldCode()));
            } 
            Map<String, Object> params = new HashMap<>();
            params.put("tableName", id);
            params.put("columnMap", dataMap);
            dataMaps.add(params);
        });
        dataMaps.forEach(params -> {
            try {
                // 插入数据
                baseMapper.insertByMap(params); 
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });
        return datas.size();
    }

Mapper

 <insert id="insertByMap"   parameterType="java.util.Map" useGeneratedKeys="true" keyColumn="id"  keyProperty="id">

        INSERT INTO  ${tableName} (
        <foreach collection="columnMap" item="value" index="key" separator=",">
            ${key}
        </foreach>
        )
        values (
        <foreach collection="columnMap" item="value" index="key" separator=",">
            #{value}
        </foreach>

        )
    </insert>

Vue


      <el-button type="warning" plain icon="Top" @click="handleImport">导入 </el-button>
 <el-dialog :title="upload.title" v-model="upload.open" width="400px" :append-to-body="true">
        <el-upload
          ref="uploadRef"
          :limit="1"
          accept=".xlsx, .xls"
          :headers="upload.headers"
          :action="upload.url+'?id='+upload.id"
          :on-progress="handleFileUploadProgress"
          :on-success="handleFileSuccess"
          :auto-upload="false"
          drag
        >
          <el-icon class="el-icon--upload">
            <i-ep-upload-filled/>
          </el-icon>
          <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
          <template #tip>
            <div class="text-center el-upload__tip">
              <div class="el-upload__tip">
                是否更新已经存在的指标数据
              </div>
              <span>仅允许导入xls、xlsx格式文件。</span>
            </div>
          </template>
        </el-upload>
        <template #footer>
          <div class="dialog-footer">
            <el-button type="primary" @click="submitFileForm">确 定</el-button>
            <el-button @click="upload.open = false">取 消</el-button>
          </div>
        </template>
      </el-dialog>

Js


const uploadRef = ref();
/*** 用户导入参数 */
const upload = ref({
  // 是否显示弹出层
  open: false,
  // 弹出层标题
  title: "",
  // 设置上传的请求头部
  headers: globalHeaders(),
  id: "",
  // 上传的地址
  url: import.meta.env.VITE_APP_BASE_API + "/tb/config/importData"
});
/** 导入按钮操作 */
const handleImport = () => {
  upload.value.title = checkbb.value.name + "报表数据导入";
  upload.value.id = checkbb.value.id;
  upload.value.open = true;
};
/**文件上传中处理 */
const handleFileUploadProgress = () => {
  upload.value.isUploading = true;
};
/** 文件上传成功处理 */
const handleFileSuccess = (response, file) => {
  upload.value.open = false;
  upload.value.isUploading = false;
  uploadRef.value?.handleRemove(file);
  proxy.$modal.msgSuccess(response.msg);
  handleSearch();
};

/** 提交上传文件 */
function submitFileForm() {
  uploadRef.value?.submit();
}

相关文章

  • Express + Three.js 抽奖程序

    抽奖程序 年会抽奖程序,3D 球体抽奖,支持奖品信息配置,参与抽奖人员信息Excel导入,抽奖结果Excel导出 ...

  • js文件上传 、导入报表excel

    这里导入分两种 :1.导入excel数据到后台:批量导入2.导入excel数据到网页:单条导入 导入的excel模...

  • 使用python处理excel

    导入xlrd模块读取excel 导入xlwt模块写入excel

  • java实现Excel导入(迭代一)

    java实现Excel导入(迭代一) 目录 1.准备工作 2.Excel导入代码及demo 3.Excel导入的时...

  • SpringBoot解析Excel

    现在很多web应用中,导入excel导出excel很常见,这篇文章就讲讲导入excel文件。 以批量导入课程为例 ...

  • Unity读取Excel文件

    首先导入Excel.dll和ICSharpCode.SharpZipLib.dll两个动态库文件 引用命名空间 u...

  • Python 动态导入对象

    背景 一个函数运行需要根据不同项目的配置,动态导入对应的配置文件运行。解决 文件结构 目的 向a模块中导入c.py...

  • Excel文件导入

    /** * 导入Excel文件数据 * @param file 将要导入的Excel文件 * @param fil...

  • Excel表格导入数据库及其下载

    Excel表格的导入导出 1.读取指定Excel到数据库 springMvc上传获取文件 //导入excel表格p...

  • 币付SDK开发文档

    SDK 说明 一. 配置工程 1. 将libbipay.dylib动态库导入项目,设置Target - Gener...

网友评论

      本文标题:动态配置导入excel

      本文链接:https://www.haomeiwen.com/subject/qwozsjtx.html