excelHelper.js

document.write('<script src="../SiteAssets/vue/xlsx.mini.min.js" type="text/javascript" charset="utf-8"></script>');
/**
 * js 导出Excel
 * @param {*} options
 * list 数据
 * header 需要转换的列名
 * excelHeader 需要展示在Excel中的列名,顺序
 * filName 文件名称(带后缀名)
 * bookType 文件后缀名
 */
function jsonToExcel(options = { list, header,excelHeader, fileName, bookType }) {
  if (options.header) {
    var count = 1;
    //根据设置的header 返回新的list
    options.list = options.list.map(item => {

      const obj = {}
      obj.序号 = count++;
      //列名
      for (const key in item) {
        if (options.header[key]) {
          obj[options.header[key]] = item[key]
        }
        //  else {
          ////原始列名
        //   obj[key] = item[key]
        // }
      }

      return obj
    })
  }
  // 1. 创建一个工作簿 workbook
  const workBook = XLSX.utils.book_new()
  // 2. 创建工作表 worksheet
  const workSheet = XLSX.utils.json_to_sheet(options.list, { header: options.excelHeader })

  // 3. 将工作表放入工作簿中
  XLSX.utils.book_append_sheet(workBook, workSheet)
  // 4. 生成数据保存
  XLSX.writeFile(workBook, options.fileName || `测试.${new Date().valueOf()}.xlsx`, {
    bookType: options.bookType || 'xlsx'
  })
}

function jsonToExcelForMergeRow(options = { list, header,excelHeader, fileName, bookType }) {
  if (options.header) {

    //这里的表头顺序规则是从sharepoint表里的顺序一样,建议在sharepoint中做好排序
    let list = JSON.parse(JSON.stringify(options.list))
      
     options.list = list.map(item => {
      const obj = {}
    
      //列名     
      for (const key in item) {

        if (options.header[key]) {
          obj[options.header[key]] = item[key];
      
        }
        //  else {
        //   obj[key] = item[key]
        // }
      }

      return obj
    })
  }

  // 1. 创建一个工作簿 workbook
  const workBook = XLSX.utils.book_new()
  // 2. 创建工作表 worksheet
  const workSheet = XLSX.utils.json_to_sheet(options.list,{header:options.excelHeader})

  // 设置工作表的记录范围
  // [列号][行号],A1 则代表 A 列的第1行
  // 列数一般是已知的(未知时可以设置为ZZ)
  // 行数则以 xlsxData 内容的长度结束即可
  // workSheet['!ref'] = `A1:AI${xlsxData.length}`;
  // s 意为 start ,即开始的单元格
  // r 是 row ,表示行号,从 0 计起
  // c 是 col ,表示列号,从 0 计起
  // const merge = [
  //   // 纵向合并,范围是第1列的行1到行2
  //   { s: { r: 0, c: 0 }, e: { r: 1, c: 0 } },
  //   // 纵向合并,范围是第2列的行1到行2
  //   { s: { r: 0, c: 1 }, e: { r: 1, c: 1 } },
  //   // 横向合并,范围是第1行的列3到列5
  //   { s: { r: 0, c: 2 }, e: { r: 0, c: 4 } },
  //   // 横向合并,范围是第1行的列6到列11
  //   { s: { r: 0, c: 5 }, e: { r: 0, c: 10 } },
  //   // 横向合并,范围是第1行的列12到列17
  //   { s: { r: 0, c: 11 }, e: { r: 0, c: 16 } },
  //   // 横向合并,范围是第1行的列18到列23
  //   { s: { r: 0, c: 17 }, e: { r: 0, c: 22 } },
  //   // 横向合并,范围是第1行的列24到列29
  //   { s: { r: 0, c: 23 }, e: { r: 0, c: 28 } },
  //   // 横向合并,范围是第1行的列30到列35
  //   { s: { r: 0, c: 29 }, e: { r: 0, c: 34 } }
  // ];

  /**
   * 动态赋值?
   * 表头不算,应该从第二行开始,如果有相同的订单号,则统计有多少个(变量为rCount),则合并多少行。没有,不合并。
   * 列是固定的,只有订单号和申请日期列需要做行合并。
   */
  // const merge = [
  //   // { s: { r: 1, c: 0 }, e: { r: 2, c: 0 } },
  //   //  { s: { r: 1, c: 1 }, e: { r: 2, c: 1 } },
  //   //  { s: { r: 2, c: 0 }, e: { r:4, c: 0 } },
  //   //  { s: { r: 2, c: 1 }, e: { r: 4, c: 1 } }
  // ];
  let merge = [];
  let list =options.list.map(item=>{
    return item.申请单号
  })
  let myObj =getRepeatNum(list);
  let newArr=[];
 // console.log(myObj);
  for(let i in myObj){
        let obj = {
            title:i,
            num:myObj[i]
        }
        newArr.push(obj)
    }
  //  console.log(newArr);
 
    let endRow =0;
    let lastRow= 0 ;
    for(v of newArr){
      
        if(lastRow==0){
          //纵向合并
          merge.push({s:{r:1,c:0},e:{r:v.num,c:0}});
          merge.push({s:{r:1,c:1},e:{r:v.num,c:1}});
          merge.push({s:{r:1,c:4},e:{r:v.num,c:4}});
          lastRow = v.num+1;
        }
        else{
          endRow =lastRow + v.num;
          if(v.num==1){
    
            // merge.push({s:{r:lastRow,c:0},e:{r:lastRow,c:0}});
            // merge.push({s:{r:lastRow,c:1},e:{r:lastRow,c:1}});
            lastRow = lastRow+1;
          }
          else{
           
            merge.push({s:{r:lastRow,c:0},e:{r:endRow-1,c:0}});
            merge.push({s:{r:lastRow,c:1},e:{r:endRow-1,c:1}});
            merge.push({s:{r:lastRow,c:4},e:{r:endRow-1,c:4}});
            lastRow = endRow+1;
          }
        }
    }
//     console.log(merge);
//  return;
    
  workSheet['!merges'] = merge;


  // 3. 将工作表放入工作簿中
  XLSX.utils.book_append_sheet(workBook, workSheet)
  // 4. 生成数据保存
  XLSX.writeFile(workBook, options.fileName || `测试.${new Date().valueOf()}.xlsx`, {
    bookType: options.bookType || 'xlsx'

  })

}
function getRepeatNum(list){ 
  var obj = {}; 
  for(var i= 0, l = list.length; i< l; i++){ 
      var item = list[i]; 
      obj[item] = (obj[item] +1 ) || 1; 
  } 
  return obj; 
}
// //用reduce时:
// //reduce:计算数组元素相加后的总和
// //reduce方法接受两个参数,第一个是函数,第二个是初始值
// // function getRepeatNum(){ 
// //   return titleList.reduce(function(prev,next){ 
// //       prev[next] = (prev[next] + 1) || 1; 
// //       return prev; 
// //   },{}); 
// // } 

// console.log(getRepeatNum());//获得{1000积分: 1, 500积分: 1, 50积分: 3}
// let myObj = this.getRepeatNum2(titleList),winningList = [];
 
// for(let i in myObj){
//     let obj = {
//         title:i,
//         num:myObj[i]
//     }
//     winningList.push(obj)
// }
// console.log(winningList)
//[{"title":"1000积分","num":1},{"title":"500积分","num":1},{"title":"50积分","num":3}]

  

//需要由英文转中文的表头  
header: {
              "Title": '申请单号',
              "BoxNo": '箱号',
              "Description": '描述',
              "ShelfNo": '货架号',
              "Address": '收货地址'
            },
//excel中表头顺序
            excelHeader: [
              '申请单号',
              '箱号',
              '描述',
              '货架号',
              '收货地址'
            ],
 exportExcel() {
              let _this = this;
              let option = {
                list: [],
                header: _this.header,
                excelHeader:_this.excelHeader,
                fileName: "文件名称" + new Date().format("yyyyMMddHHmmss") + ".xlsx",
                bookType: "xlsx"

              };
              //如果有选中的数据,则导出选中的数据。
              if (_this.multipleSelection.length > 0) {
                option.list = _this.multipleSelection;
              }
              else {
                //如果没有选中的数据,则导出已经查询出来的所有数据。
                option.list = _this.tableData;
              }
             // jsonToExcelForMergeRow(option);
            //jsonToExcel(option);

            },

  

posted on 2022-11-07 17:14  橙色Key  阅读(298)  评论(0)    收藏  举报