【问题标题】:electron sheetjs download generated file from JSONelectron sheetjs 从 JSON 下载生成的文件
【发布时间】:2020-06-28 20:21:54
【问题描述】:

我有一个带有 VueJS 的 Electron 应用程序,我尝试使用 sheetjs 下载生成的 XLS,但 provided 解决方法在我的情况下不起作用。这是我一直在尝试的:

 exportData(id, type) {
      // eslint-disable-next-line no-console
      console.log(type);

      (async () => {
        const data = await ProjectController.getProject(id);
        const ws = XLSX.utils.json_to_sheet(JSON.parse(data.excel));
        // eslint-disable-next-line no-console

        let wb = XLSX.utils.book_new();
        XLSX.utils.book_append_sheet(wb, ws, "test");
        let o = dialog.showSaveDialog();
        // eslint-disable-next-line no-console
        console.log(o);

        XLSX.writeFile(wb, o);

        // eslint-disable-next-line no-console
        //console.log(file);
      })();
    }

在控制台中我收到以下错误Uncaught (in promise) TypeError: o.file.lastIndexOf is not a function。

如果我使用以下代码

  (async () => {
        const data = await ProjectController.getProject(id);

        const ws = (XLSX.WorkSheet = XLSX.utils.json_to_sheet(
          JSON.parse(data.excel)
        ));

        let wb = XLSX.utils.book_new();
        XLSX.utils.book_append_sheet(wb, ws, "test");


        const file = XLSX.write(wb, {
          bookType: "xlsx",
          type: "buffer",
          compression: true
        });

        let savePath = dialog.showSaveDialog({});
        XLSX.writeFile(file, savePath);

        fs.writeFileSync("test1.xlsx", file);


      })();

该文件将被下载到项目文件夹的根目录中,之前没有弹出窗口。但我希望能够将这些文件下载到用户选择的文件夹中。

这是我的 package.json

{
  "name": "movie-translation-tool",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint",
    "electron:build": "vue-cli-service electron:build",
    "electron:serve": "vue-cli-service electron:serve",
    "i18n:report": "vue-cli-service i18n:report --src './src/**/*.?(js|vue)' --locales './src/locales/**/*.json'",
    "postinstall": "electron-builder install-app-deps",
    "postuninstall": "electron-builder install-app-deps"
  },
  "main": "background.js",
  "dependencies": {
    "awesome-phonenumber": "^2.24.0",
    "core-js": "^3.4.3",
    "dropbox": "^4.0.30",
    "knex": "^0.20.3",
    "mssql": "^6.0.1",
    "objection": "^2.0.3",
    "pdf2json": "^1.2.0",
    "sqlite3": "^4.1.1",
    "vee-validate": "^3.1.3",
    "vue": "^2.6.10",
    "vue-i18n": "^8.0.0",
    "vue-router": "^3.1.3",
    "vue-video-player": "^5.0.2",
    "vuetify": "^2.1.0",
    "vuetify-image-input": "^19.1.0",
    "vuex": "^3.1.2",
    "xlsx": "^0.15.3"
  },
  "devDependencies": {
    "@mdi/font": "^4.6.95",
    "@mdi/js": "^4.6.95",
    "@vue/cli-plugin-babel": "^4.1.0",
    "@vue/cli-plugin-eslint": "^4.1.0",
    "@vue/cli-plugin-router": "^4.1.1",
    "@vue/cli-plugin-vuex": "^4.1.1",
    "@vue/cli-service": "^4.1.0",
    "babel-eslint": "^10.0.3",
    "electron": "^6.0.0",
    "eslint": "^5.16.0",
    "eslint-plugin-vue": "^5.0.0",
    "material-design-icons-iconfont": "^5.0.1",
    "sass": "^1.19.0",
    "sass-loader": "^10.0.0",
    "vue-cli-plugin-electron-builder": "^1.4.3",
    "vue-cli-plugin-i18n": "^0.6.1",
    "vue-cli-plugin-vuetify": "^2.0.2",
    "vue-template-compiler": "^2.6.10",
    "vuetify-loader": "^1.3.0"
  },
  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/essential",
      "eslint:recommended"
    ],
    "rules": {},
    "parserOptions": {
      "parser": "babel-eslint"
    }
  },
  "browserslist": [
    "> 1%",
    "last 2 versions"
  ]
}

如何正确地将文件附加到窗口?

【问题讨论】:

  • 是否弹出保存对话框?您在哪里使用此功能,在主进程或渲染器进程中?另外,请更新您的package.json 内容。
  • 对于第一个示例,我有弹出窗口,但没有保存任何内容,使用第二个代码 sn-p 我没有弹出窗口,文件保存在我的项目根目录中。其实exportData是一个VUE方法,点击按钮触发。
  • 请检查我的答案,如果它适合你,请告诉我。

标签: file vue.js download electron sheetjs


【解决方案1】:

对话方法dialog.showSaveDialog返回一个解析为对象的promise,它不返回字符串:

dialog.showSaveDialog([browserWindow, ]options)

返回Promise<Object> - 使用包含 以下:

  • canceled Boolean - 对话框是否被取消。
  • filePath 字符串(可选)- 如果对话框被取消,这将是 undefined。
  • bookmark 字符串(可选)macOS mas - Base64 编码字符串,其中包含已保存文件的安全范围书签数据。 必须启用securityScopedBookmarks 才能显示。 (为了 返回值,请参见此处的表格。)

对于dialog.showSaveDialog,您必须使用await 或使用dialog.showSaveDialogSync,此外,您可以使exportData 异步,而不是创建内部异步函数。

尝试像这样重构你的代码:

async exportData(id, type) {
  const data = await ProjectController.getProject(id);
  const ws = XLSX.utils.json_to_sheet(JSON.parse(data.excel));
  const wb = XLSX.utils.book_new();

  XLSX.utils.book_append_sheet(wb, ws, "test");

  let { filePath, canceled } = await dialog.showSaveDialog();

  if (!canceled) {
    XLSX.writeFile(wb, filePath);
  }
}

【讨论】:

  • 非常感谢!重构工作很好。是否可以将给定的文件名推送到弹出窗口?
  • 是的,您可以使用defaultPath 选项属性来设置建议的文件名,甚至是对话框的路径(例如await dialog.showSaveDialog(null, { defaultPath: "Project-data.xls" }))。 defaultPath String (可选) - 绝对目录路径、绝对文件路径或默认使用的文件名.
猜你喜欢
  • 2020-07-05
  • 2016-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-08
  • 1970-01-01
  • 2012-02-24
  • 2015-06-26
相关资源
最近更新 更多