Newer
Older
smart-metering-front / src / views / business / lab / excelEdit / methods / file.ts
/**
 * 文件公共方法
 */

import * as GC from '@grapecity-software/spread-sheets'
// 文件类型常量定义
const FileType = {
  SJS: 'sjs',
  Excel: 'xlsx',
  SSJson: 'ssjson',
}

/**
 * 获取文件类型
 * @param file 文件
 * @returns
 */
export function getFileType(file: Blob) {
  if (!file) {
    return
  }
  if (!isBlob(file)) {
    return
  }
  const extensionName = file.type
  if (extensionName === 'sjs') {
    return FileType.SJS
  }
  else if (extensionName === 'xlsx' || extensionName === 'xlsm') {
    return FileType.Excel
  }
  else if (extensionName === 'ssjson' || extensionName === 'json') {
    return FileType.SSJson
  }
  else {
    console.log('getFileType:未获取到文件类型')
  }
}
/**
 * 判断文件是否是blob类型
 * @param file
 * @returns
 */
function isBlob(file: unknown): file is Blob {
  return file instanceof Blob
}

/**
 * @param spread spread实例
 * @param file 文件
 * @returns
 */
export async function importFile(spread: any, file: Blob) {
  const fileType = getFileType(file)
  console.log('获取到的文件类型', fileType, fileType === FileType.SJS)

  return new Promise((resolve) => {
    if (fileType === FileType.SJS) {
      spread.open(
        file,
        () => {
          console.log('importFile:导入sjs文件成功')
          resolve('')
        },
        (e: any) => {
          console.log('importFile:上传sjs文件发生错误', e)
        },
      )
    }
    else {
      spread.import(
        file,
        () => {
          console.log('importFile:导入文件成功')
          resolve('')
        },
        (e: any) => {
          console.log('importFile:上传文件发生错误', e)
        },
      )
    }
  })
}

// 获取文件导出选项
function getExportOptions(fileType: any) {
  return {
    fileType: GC.Spread.Sheets.FileType[fileType],
    // 包含绑定数据源,文件中包含数据绑定时,是否导出绑定数据
    includeBindingSource: true,
    // 是否保存为视图
    saveAsView: true,
    // 导出文件时是否包含样式
    includeStyles: true,
    // 导出文件时是否包含公式
    includeFormulas: true,
    // 包含未使用名称,导出文件时是否包含无用的名称管理器,若文件中包含大量无用的名称管理器,设置为true可减小文件大小
    includeUnusedNames: true,
    // 包含有样式但无数据的最小范围单元格,是否导出无用的空单元格,文件中包含大量空白单元格,希望提升导出效率时,建议开启。
    includeEmptyRegionCells: true,
    // 包含自动合并的单元格,导出文件是否将自动合并的单元格视为真是合并单元格,当文件中包含自动合并的单元格,导出Excel时,希望成为真实的合并单元格时,建议开启
    includeAutoMergedCells: true,
    // 导出时是否包含计算缓存数据,计算缓存数据可以更快的打开文件。
    includeCalcModelCache: false,
  }
}

/**
 * 下载文件操作
 * @param blob 文件blob
 * @param filename 文件名称
 */
function saveAs(blob: Blob, filename: string) {
  const link = document.createElement('a')
  link.href = URL.createObjectURL(blob)
  link.download = filename
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
}

/**
 * 文件导出
 * @param spread
 * @param fileType 文件类型
 * @param getFileName 导出文件名称
 * @param onlyFetchFile 仅获取文件, 不进行导出下载
 */
export function exportFile(
  spread: any,
  fileType: string,
  onlyFetchFile = false,
  getFileName = 'exportFile',
) {
  const options = getExportOptions(fileType)
  const fileName = `${getFileName}.${fileType}`
  return new Promise((resolve) => {
    // 根据文件类型调用不同的导出方法
    if (fileType === FileType.SJS) {
      spread.save(
        (blob: Blob) => {
          if (!onlyFetchFile) {
            saveAs(blob, fileName)
          }
          console.log('导出成功回调', blob)
          resolve(blob)
        },
        (error: any) => {
          console.log('导出失败回调', error)
        },
        options,
      )
    }
    else {
      spread.export(
        (blob: Blob) => {
          if (!onlyFetchFile) {
            saveAs(blob, fileName)
          }
          console.log('导出成功回调', blob)
          resolve(blob)
        },
        (error: any) => {
          console.log('导出失败回调', error)
        },
        options,
      )
    }
  })
}