【问题标题】:Convert pdf to html files using node.js and pdf.js使用 node.js 和 pdf.js 将 pdf 转换为 html 文件
【发布时间】:2019-10-24 21:04:48
【问题描述】:

我想使用 pdf.js 将 pdf 转换为 html 页面。 Pdf.js 在浏览器中执行此操作,但是否可以在后端获取浏览器呈现的那些 html 页面,从而将 n 个页面的 pdf 转换为 n 个 html 文件。我使用 node.js 作为后端。我尝试过 pdf2html 和其他类似的 npm 模块,但它们效果不佳,并且在某些 pdf 上存在问题。谢谢你的建议。

【问题讨论】:

  • 您的解决方案在这里-> bytescout.com/articles/…
  • 这不是免费的! :(
  • pdf.js 将 pdf 转换为图像(画布、png 等)。它不会将 PDF 转换为 HTML。

标签: javascript html node.js pdf.js


【解决方案1】:

也许我发现了类似的东西 - 我正在使用本地 PDF 文件和浏览器。我对现成的 viewer.js / PDF.js 做了一些小改动,应该可以同时使用 Node.js 和浏览器进行处理。

此脚本包含由 viewer.js Webpack 的参数指定的 PDF 并启动浏览器。

const fs = require('fs');
const path = require('path');
const pdf = require('process').argv[2];
const chp = require('child_process');
const datauri = require(path.join(process.env.APPDATA, 'npm/node_modules', 'datauri'));
datauri(pdf, (err, content, meta) => {
    if (err) {
        throw err;
    }
    const viewerJSpath = path.join(__dirname, './viewer.js');
    let wp = fs.readFileSync(viewerJSpath, 'utf-8');
    const pdfName = 'compressed.tracemonkey-pldi-09.pdf';
    const srcPos = [wp.indexOf(pdfName)];
    srcPos.push(srcPos[0] + pdfName.length);
    let HOSTED_VIEWER_ORIGINS = wp.indexOf('HOSTED_VIEWER_ORIGINS');
    HOSTED_VIEWER_ORIGINS = wp.indexOf(']', HOSTED_VIEWER_ORIGINS);
    wp = wp.substr(0, srcPos[0]) + content +
    wp.substr(srcPos[1], HOSTED_VIEWER_ORIGINS - srcPos[1]) + ', "file://"' +
    wp.substr(HOSTED_VIEWER_ORIGINS);
    fs.writeFileSync(viewerJSpath, wp, 'utf-8');
    const c = path.join(__dirname, 'viewer.html');
    chp.execSync(c);
});

然后尝试将原始宽度作为下一个样式参数添加到 renderTextLayer 的 appendText 方法,并将元素按位置排序到 TextLayerBuilder 的渲染方法 next2 this.textLayerDiv.appendChild(textLayerFrag);

All mentioned PDF.js changes on my Github 似乎只需要 webbuild 文件夹(npm i -g datauri fox 示例除外)。


使用 puppeteer 和稍微修改的 PDF.js 可以直接转换(head/less 都可以,但元素大小略有不同)

const fs = require('fs');
const path = require('path');
const pdf = require('process').argv[2];
const datauri = require(path.join(process.env.APPDATA, 'npm/node_modules', 'datauri'));
const puppeteer = require(path.join(process.env.APPDATA, 'npm/node_modules', 'puppeteer'));
datauri(pdf, (err, content, meta) => {
    if (err) {
        throw err;
    }
    const viewerJSpath = path.join(__dirname, './viewer');
    let wp = fs.readFileSync(viewerJSpath + 'Src.js', 'utf-8');
    const pdfName = 'compressed.tracemonkey-pldi-09.pdf';
    const srcPos = [wp.indexOf(pdfName)];
    srcPos.push(srcPos[0] + pdfName.length);
    let HOSTED_VIEWER_ORIGINS = wp.indexOf('HOSTED_VIEWER_ORIGINS');
    HOSTED_VIEWER_ORIGINS = wp.indexOf(']', HOSTED_VIEWER_ORIGINS);
    wp = wp.substr(0, srcPos[0]) + content +
    wp.substr(srcPos[1], HOSTED_VIEWER_ORIGINS - srcPos[1]) + ', "file://"' +
    wp.substr(HOSTED_VIEWER_ORIGINS);
    fs.writeFileSync(viewerJSpath + '.js', wp, 'utf-8');
    (async () => {
        const browser = await puppeteer.launch({
            // headless: false
        });
        const page = await browser.pages();
        const c = path.join(__dirname, 'viewer.html');
        await page[0].goto('file:///' + c);
        page[0].exposeFunction('reader', (elLists) => {
            fs.writeFileSync(path.join(__dirname, 'PDFtexts.txt'), JSON.stringify(elLists, null, 4));
            setTimeout(() => { browser.close(); }, 100);
        });
    })();
});

puppeteer/chromium 所需的修复:

const message = exception?.message; // => exception.message
page: this.pageLabel ?? this.id // => this.pageLabel || this.id

viewer.js => viewerSrc.js 基本补充:

function webViewerPageRendered({
...
  if (pageNumber < PDFViewerApplication.pagesCount) {
    arguments[0].source.eventBus.dispatch("pagenumberchanged", {
      value: pageNumber + 1
    }); // generate all remaining pages
  }
}

class BaseViewer {
  constructor(options) {
    this.pageNo = []; // rendered pages array
...
  _setCurrentPageNumber(val, resetCurrentPageView = false) {
...
    if (this.pageNo.indexOf(val) < 0) {
      this.pageNo.push(val);
    }
    if (this.pagesCount - 1 <= this.pageNo.length) {
      window.reader(elLists); // sent result back 2 node.js
    }

结果看起来像 {PageNo:{ElNo:{data}, ...}, ...},可以简单地翻译成网页或进一步处理。

{
    "1": {
        "0": {
            "x": 99.9871,
            "y": 98.0496,
            "w": 557.695,
            "h": 22,
            "text": "Trace-based Just-in-Time Type Specialization for Dynamic",
            "ff": "sans-serif",
            "fs": "22.2695px",
            "cssText": "left: 99.9871px; top: 98.0496px; width: 557.695px; font-size: 22.2695px; font-family: sans-serif; transform: scaleX(0.970163);"
        },
        "1": {
            "x": 327.478,
            "y": 122.793,
            "w": 102.707,
            "h": 22,
            "text": "Languages",
            "ff": "sans-serif",
            "fs": "22.2695px",
            "cssText": "left: 327.478px; top: 122.793px; width: 102.707px; font-size: 22.2695px; font-family: sans-serif; transform: scaleX(0.932262);"
        },
...
    "2": {
        "0": {
            "x": 393.677,
            "y": 90.3408,
            "w": 192.909,
            "h": 11,
            "text": "1 for (var i = 2; i < 100; ++i) {",
            "ff": "monospace",
            "fs": "11.1347px",
            "cssText": "left: 393.677px; top: 90.3408px; width: 192.909px; font-size: 11.1347px; font-family: monospace; transform: scaleX(0.875232);"
        },
        "1": {
            "x": 67.0588,
            "y": 91.7599,
            "w": 173.346,
            "h": 11,
            "text": "Hence, recording and compiling a trace",
            "ff": "sans-serif",
            "fs": "11.1347px",
            "cssText": "left: 67.0588px; top: 91.7599px; width: 173.346px; font-size: 11.1347px; font-family: sans-serif; transform: scaleX(0.895175);"
        },

【讨论】:

  • 在线演示-PDF下载改为HTM下载(文本层)eltomjan.github.io/JStoolsSPAdemos/pdf2htm/web/viewer.html
  • 完美作品!!那么如何使用您的解决方案将 pdf 转换为 html 呢?我可以通过 CMD 的一些命令来做到这一点,还是应该用一些 js 命令创建 html 文件?
  • 还不确定 ;-),检查了我的 github,有一个简单的 Node.js 脚本,我曾在我盲人朋友的机器上使用过它,并使用一些批处理文件作为默认的 PDF 查看器,以获得最佳的屏幕阅读器体验。它使用 puppeteer 进行这种自动化(没有太安全的通用浏览器)。 Mozilla 有一个经典的论点“这样的问题很可能是在许多文档中它不能很好地工作,同时记住 PDF 文档可以使用从左到右、从右到左或上-自下而上的阅读顺序,还有代码的性能/可维护性的问题。”
  • ... 一般来说,像 issue github.com/mozilla/pdf.js/issues/6269 这样的问题可能是这里最合理的方式。
猜你喜欢
  • 2013-05-23
  • 2014-04-07
  • 1970-01-01
  • 2019-08-19
  • 2018-01-08
  • 2013-01-11
  • 2011-06-17
  • 2012-05-05
相关资源
最近更新 更多