sqlserver中excel 入库的思考

 

 

1.纯使用sqlserver 的存储过程

   在sqlserver中有 关于打开excel 的函数 可以写一个 存储过程搞定 例如下面:

create procedure ExcelRead
as

delete from test

insert into test
select *
 from OPENROWSET('Microsoft.ACE.OLEDB.12.0',
 'Excel 12.0;Database=C:\Users\xin.wang3\Desktop\MyTest.xlsx;',
 'SELECT * FROM [Sheet1$]')

 exec ExcelRead

但是 这里数据库中必须含有Microsoft.ACE.OLEDB.12.0 的引擎插件

个人感觉这种方法:让数据导入下沉到 db层 不用使用 外部的代码 干扰

2.使用SSMS用可视化窗口进行导入

使用方法参考 https://www.cnblogs.com/zhangliangzlee/p/3585862.html?utm_source=tuicool&utm_medium=referral

3.使用外部的代码实现

由于种种原因 dba 不愿意加装插件 ssms 也不太自动化 所以我就使用java 代码完成

本项目为 springboot 项目 就启动 定时器 扫描共享目录中的 excel 文件

关注过 阿里的 easyexecl 所以 就 使用这个 execl 框架

@Component
@Slf4j
public class ScheduleJob {

  @Autowired
  private ExcelCacheMapper customerCacheMapper;

//  @Scheduled(cron = "0 22 14 * * ? ")
//  public void twoSecondExport(){
//    log.info("==============ssssssss================");
//    inportExcelToDatabase(ParseExcelType.E1CustomerType);
//    log.info("==============ssssssss================");
//  }
//
//  @Scheduled(cron = "0 22 14 * * ? ")
//  public void fourSecondExport(){
//    inportExcelToDatabase(ParseExcelType.ITSCARCacheType);
//  }

  public void inportExcelToDatabase(ParseExcelType excelType){
    InputStream inputStream = null;
    ExcelListener listener = null;
    try {
      inputStream = new FileInputStream(new File(excelType.getSourcePath()));
      // 解析每行结果在listener中处理
      listener = new ExcelListener(excelType.getType());
      ExcelReader excelReader = new ExcelReader(inputStream,  null, listener);

      if(excelType.getType() == SkuPrice.class){
        //use map insert
        excelReader.read(new Sheet(excelType.getSheetNo(), excelType.getHeadLine(), null));
      }else{
        //use javaBean insert
        excelReader.read(new Sheet(excelType.getSheetNo(), excelType.getHeadLine(), excelType.getType()));
      }
      List datas = listener.getDatas();
      switch (excelType){
        case E1CustomerType:
          this.insertList(datas,s->customerCacheMapper.insertEoneCustomerCacheList(s));
          //TODO refresh cache to main table

          break;
        case SaleCustomerType:
          this.insertList(datas,s->customerCacheMapper.insertSaleCustomerCacheList(s));
          //TODO refresh cache to main table

          break;
        case ITSCARCacheType:
          this.insertList(datas,s->customerCacheMapper.insertITSCARCacheList(s));
          //TODO refresh cache to main table

          break;
        case InventoryExcelType:
          this.insertList(datas,s->customerCacheMapper.insertIventoryCacheList(s));
          //TODO refresh cache to main table

          break;
        case SkuPriceType:
          this.insertList(datas,s->customerCacheMapper.insertSkuPriceCacheList(s));
          //TODO refresh cache to main table
          break;
        default:
          break;
      }
    } catch (Exception e) {
      log.error(e.toString());
    } finally {
      listener.clear();
      try {
        inputStream.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }

  private void insertList(List datas,Consumer<List> con){
    for (int i= 0;i<=datas.size()/100;i++){
      if (i==datas.size()/100){
        con.accept(datas.subList(i*100,datas.size()));
      }else {
        con.accept(datas.subList(i*100,(i+1)*100));
      }
    }
  }

}
@Slf4j
public class ExcelListener<T> extends AnalysisEventListener {


  public ExcelListener(Class listenerClazz) {
    TITLE.put("SKU_NBR","skuNbr");
    TITLE.put("SKU Desc","skuDesc");
    TITLE.put("2019LP CNY","lpCny");
    TITLE.put("AM Disc%","amDisc");
    TITLE.put("RM Disc%","rmDisc");
    TITLE.put("SD Disc%","sdDisc");
    TITLE.put("SKU Size","skuSize");
    this.listenerClazz = listenerClazz;
  }

  private List datas = new ArrayList<>();

  private Class listenerClazz;

  public static final LinkedHashMap<String,String> TITLE_FILED = new LinkedHashMap<>();
  public static final HashMap<String,String> TITLE = new HashMap<>();

  @Override
  public void invoke(Object object, AnalysisContext context) {
    if (listenerClazz.getName().indexOf("SkuPrice") != -1){
      Integer rowNum = context.getCurrentRowNum();
      List<String> list = (List<String>)object;
      if (TITLE_FILED.isEmpty()){
        list.stream().forEach(s->{
            TITLE_FILED.put(TITLE.get(s),null);
        });
      }
      if (rowNum>0){
        LinkedHashMap<String, String> linkedHashMap = this.copyMap();
        int i = 0;
        for (String key:linkedHashMap.keySet()){
          String vaule = list.get(i);
          if (isIntTitle(key)){
            try {
              vaule = Integer.valueOf(vaule).toString();
            }catch (NumberFormatException e){
              vaule = null;
            }
          }
          linkedHashMap.put(key,vaule);
          i++;
        }
        linkedHashMap.remove(null);
        datas.add(linkedHashMap);
      }
    }else{
      datas.add(object);
      //log.info(object.toString());
    }
  }

  private boolean isIntTitle(String key){
    if ("amDisc".equals(key) || "rmDisc".equals(key)|| "sdDisc".equals(key)|| "lpCny".equals(key)){
      return true;
    }
    return false;
  }

  private LinkedHashMap<String,String> copyMap(){
    LinkedHashMap<String,String> linkedHashMap = new LinkedHashMap<>();
    TITLE_FILED.forEach((k,v)->linkedHashMap.put(k,null));
    return linkedHashMap;
  }


  @Override
  public void doAfterAllAnalysed(AnalysisContext context) {
    // datas.clear();//解析结束销毁不用的资源
  }

  private Class getThisClass(){
     return  Util.getActualArgumentType(this.getClass(), 0);
  }

  public void clear() {
    datas.clear();
  }
  public List<T> getDatas() {
    return datas;
  }
  public void setDatas(List<T> datas) {
    this.datas = datas;
  }
}
@Getter
@Setter
@Table(name = "itsc_ar_cache")
public class ITSCARCache  extends BaseRowModel {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;

  @ExcelProperty(index = 3)
  @Column(name = "bt_no")
  private String bill2NO;

  @ExcelProperty(index = 27)
  @Column(name = "bill_date")
  private Date billDate;

  @ExcelProperty(index = 28)
  @Column(name = "expire_date")
  private Date expireDate;

  @ExcelProperty(index = 35)
  @Column(name = "indent_no")
  private String indentNO;

  @ExcelProperty(index = 33)
  @Column(name = "bill_no")
  private String billNO;

  @ExcelProperty(index = 40)
  @Column(name = "overdue_amount")
  private BigDecimal overdueAmount;

}

主要思路就是 excel 的列的index 映射到实体类中 @ExcelProperty(index = 35) 方法

在excelReader.read(new Sheet(excelType.getSheetNo(), excelType.getHeadLine(), excelType.getType()));中封装到其中

但是 续期中有一个 execl 中的index 不明确可能会改变 但是 列明不变 在easyexcel 中ExcelProperty中value 是存在bug

https://github.com/alibaba/easyexcel/issues/213

所以就手动的使用map实现 详情见代码

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值