2

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

 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"
  ]
}

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

4

1 回答 1

1

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

dialog.showSaveDialog([browserWindow, ]options)

返回Promise<Object>- 使用包含以下内容的对象解析:

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

您必须awaitfordialog.showSaveDialog或使用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);
  }
}
于 2020-03-23T10:46:59.120 回答