持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第7天, 点击查看活动详情

本篇文章主要介绍如何获取剪切板上的文件数据,主要是通过electron的clipboard模块来实现的。

二、实现方案

主要有以下技术要点:

  • 在MacOS系统中,能通过 clipboard.read('NSFilenamesPboardType') 读取到一个被复制的文件或文件夹列表的XML格式描述文本。
  • 在windows系统中,能通过 clipboard.read('CF_HDROP') 读取剪切板的上的文件名数组。
  • 在MacOS系统中,能通过 clipboard.read('public.file-url') 读取剪切板上的单个文件。
  • 在windoows系统中能通过 clipboard.read('FileNameW') 读取剪切板上单个文件。
  • 通过 clipboard.readImage('clipboard') 能获取剪切板上的图片。
  • 这其中,在windows系统中读取含有中文名称时,路径格式会有问题,因此在读取文件信息的时候需要如下写法,多文件同理

    clipboard.readBuffer('FileNameW').toString('ucs2').replace(RegExp(String.fromCharCode(0), 'g'), '')
    

    electron中读取剪切板上文件信息,完整版实现代码如下

    const { clipboard } = window.require('electron').remote
    // 获取剪切板上文件路径
    getClipboardFiles () {
      console.log('Files from clipboard')
      // 用于存放剪切板上的文件路径集合
      let filePath = []
      if (this.$isMac) { // 若当前在mac系统中
        if (clipboard.has('NSFilenamesPboardType')) { // 若存在多个文件
          const tagContent = clipboard.read('NSFilenamesPboardType').match(/<string>.*<\/string>/g)
          filePath = tagContent ? tagContent.map(item => item.replace(/<string>|<\/string>/g, '')) : []
        } else { // 仅单个文件的时候
          const clipboardImage = clipboard.readImage('clipboard')
          if (!clipboardImage.isEmpty()) { // 若此文件为图片
            console.log('upload image from clipboard')
            const png = clipboardImage.toPNG()
            const fileInfo = {
              buffer: png,
              mimetype: 'image/png',
              originalname: uuid(8, 16) + '.png'
            filePath = [fileInfo]
          } else { // 读取单个文件
            filePath = [clipboard.read('public.file-url').replace('file://', '')].filter(item => item)
      } else { // 若当前在windows系统中
        if (clipboard.has('CF_HDROP')) { // 若剪切板上有多个文件
          const rawFilePathStr = clipboard.readBuffer('CF_HDROP').toString('ucs2') || ''
          let formatFilePathStr = [...rawFilePathStr]
            .filter((_, index) => rawFilePathStr.charCodeAt(index) !== 0)
            .join('')
            .replace(/\\/g, '\\')
          const drivePrefix = formatFilePathStr.match(/[a-zA-Z]:\\/)
          if (drivePrefix) {
            const drivePrefixIndex = formatFilePathStr.indexOf(drivePrefix[0])
            if (drivePrefixIndex !== 0) {
              formatFilePathStr = formatFilePathStr.substring(drivePrefixIndex)
            filePath = formatFilePathStr
              .split(drivePrefix[0])
              .filter(item => item)
              .map(item => drivePrefix + item)
        } else { // 若为单个文件
          const clipboardImage = clipboard.readImage('clipboard')
          if (!clipboardImage.isEmpty()) { // 当前文件为图片类型
            console.log('upload image from clipboard')
            const png = clipboardImage.toPNG()
            const fileInfo = {
              buffer: png,
              mimetype: 'image/png',
              originalname: uuid(8, 16) + '.png'
            filePath = [fileInfo]
          } else { // 读取单个文件
            filePath = [
              clipboard.readBuffer('FileNameW').toString('ucs2').replace(RegExp(String.fromCharCode(0), 'g'), '')
            ].filter(item => item)
      console.log('get file path from clipboard:', filePath)
      return filePath
    

    我们通过以上方法能获取到剪切板上的文件路径,后续可以通过fs.read()方法读取文件信息,进行对应的文件操作。

    在剪切板这一部分,electron的api说明并不明确。因此找了许多关于剪切板的资料。

  • learn.microsoft.com/en-us/windo…
  • www.codeproject.com/Reference/1…
  • github.com/electron/el…
  • github.com/electron/el…
  • github.com/electron/el…
  • 本篇完结! 撒花 ! 感谢观看! 希望能帮助到你!

  • 私信
  •