如何在电子浏览器窗口中查看 PDF?

How to view a PDF in an Electron BrowserWindow?

所以我有这个 Electron 应用程序,在其中一个 .html 文件中,我 link 另一个脚本为程序提供了一些实用功能,其中之一就是这个:

function openPDF(filePath){
    let pdfWindow = new electron.remote.BrowserWindow({
        icon: './build/icon.png',
        width: 1200,
        height: 800,
        webPreferences: {
            plugins: true
        }
    });

    pdfWindow.loadURL(url.format({
        pathname: filePath,
        protocol: 'file:',
        slashes: true
    }));

    pdfWindow.setMenu(null);

    pdfWindow.on("closed", function () {
        pdfWindow = null
    });
}

所以这应该使用 Electron 的集成 PDF-Viewer(它使用 Chromium)在新的 window 中打开 PDF。我使用了臭名昭著的 plugins: true,我尝试了大部分 thousands of preferences you can define for a BrowserWindow 但它总是打开 window 然后开始下载文件而不是显示它。

我检查了文件路径、"imports" 等三次,更新了所有内容,但我似乎找不到问题所在。自 1.6.4 以来,Electron 原生支持此功能,但它对我不起作用。

帮助我,Stack Overflow,你是我唯一的希望。

2020 年更新:

@karthick 正确地指出这是一个禁用插件的错误,尽管 plugins: trueThe Issue exists since 3.0.0(2018 年 9 月 18 日)和 今天仍然修复 终于在版本 9 中修复了!

使用此命令将您的电子版本更新到 9.X.X 或更高版本以启用该功能:

npm update electron

您可以检查 package.json 中的 devDependencies,它应该在您的项目文件夹中找到。它应该看起来像这样:

"devDependencies": {
    "electron": "^9.0.0"
},

旧答案:

由于长期存在的 GitHub 问题往往会变得相当混乱,我将根据开发的要点更新此答案。您还可以在答案末尾找到三个解决方法。

更新:

  1. 3 月 19 日:A fix is on the way
  2. 5 月 19 日:上述修复目前暂停 等待 better extension support.
  3. 6 月 28 日:更好 扩展支持 预计不会很快出现。
  4. 7 月 16 日:The fix 不再积极处理。引用 开发商:

The main thing I ran into trying to port over Chromium's viewer was its dependency on the chromium extension system. Electron supports only a portion of that system which made it difficult to integrate the viewer.

  1. 7 月 25 日:improvement of the extension support which was merged and a follow-up tracking issue was created. This increased the likeliness of a continuation of the work on the fix.

    取得了重大进展
  2. 8 月 28 日:目前没有人在进行修复。如果你想更快地解决这个问题,你可以put a bounty on this issue over on BountySource

  3. 11 月 19 日:The fix 关闭,分支被删除。开发商报价:

We're still intending to one day restore the PDF viewer, but it relies on us first migrating to use Chrome's extensions library instead of our own shim, as the PDF viewer in Chromium is implemented as an extension.

  1. 1 月 2 日:尽管 a bounty of ,600 over on BountySource

    仍然没有人在做这件事
  2. 1月21日:扩展支持持续完善中(tracking issue) and a new fix已引入

  3. 2 月 13 日:The new fix 已合并,问题已关闭。 看来这将在 Electron 10 中得到解决! 开发者引述:

This should be ready to test out in the next 10.x nightly. I'm hoping to backport to 9.x as well, though it may not end up sticking if it causes issues.

解决方法:

  1. 您可以通过降级到最新的 2.X.X 使其正常工作。为此,请使用以下命令:

     npm install electron@"<3.0.0" --save-dev
    

但是请记住,only the latest three stable major versions are supported by the Electron team 这意味着 2.X.X 不再接收安全补丁

  1. 或者您可以调用系统打开文件。它将选择分配给 PDF 的默认程序:

     shell.openItem(fullPath);
    

只需确保路径 (fullPath) 始终使用 path.resolve(app.getAppPath(), filePath) 之类的内容正确解析,因为它可能会在您构建应用程序时更改。

  1. 另一种解决方法是使用 PDF.js 之类的东西,它不完全提供 Chrome PDF 查看器的完整功能集(例如,缺少字段完成)但是对于大多数应用程序来说可能已经足够好了。这是一个捕获下载事件并将其路由到 PDF.js-viewer:

    的示例实现
     const { BrowserWindow, session } = require('electron')
     session.defaultSession.on('will-download', (event, item, webContents) => {
         if (item.getMimeType() === 'application/pdf' && item.getURL().indexOf('blob:file:') != 0) {
             event.preventDefault();
             new BrowserWindow().loadFile(path.resolve(__dirname, `pdfjs/web/viewer.html?file=${item.getURL()}`));
         }
     })