You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Node.js搭建的PDF上传下载网站中添加PDF预览功能

嘿,这个需求我在好几个项目里都碰到过,给你整理几个实用的实现方案,你可以根据自己的技术栈和需求挑:

方案1:利用浏览器原生PDF支持(最快最简)

现在主流浏览器(Chrome、Firefox、Edge等)都原生支持PDF渲染,不用额外加任何依赖,几行代码就能搞定。

实现方式

直接用 <iframe> 或者 <embed> 标签把PDF文件嵌入页面:

<!-- 推荐用iframe,兼容性更稳定 -->
<iframe 
  src="/your-server-path/to/target.pdf" 
  width="100%" 
  height="800px" 
  title="PDF在线预览"
  sandbox="allow-same-origin allow-scripts" <!-- 可选,增加安全性 -->
></iframe>

<!-- 或者用embed标签 -->
<embed 
  src="/your-server-path/to/target.pdf" 
  type="application/pdf" 
  width="100%" 
  height="800px"
>

优缺点

  • ✅ 优点:零依赖、代码量极少、开发速度快,原生支持缩放、分页、搜索等基础功能
  • ❌ 缺点:UI和交互受浏览器控制,不同浏览器显示样式有差异,无法自定义预览栏、添加专属下载按钮等个性化功能
方案2:用第三方JS库实现高度自定义预览(推荐复杂场景)

如果需要完全控制预览的UI和交互(比如自定义分页按钮、添加标注、集成下载功能到预览区),最常用的就是Mozilla开源的 PDF.js,这也是很多大厂PDF预览功能的底层依赖。

实现步骤

  1. 先把PDF.js的核心库和Worker文件下载到本地(避免外链,直接部署到自己的服务器)
  2. 在页面中准备渲染容器和交互控件,然后写JS逻辑加载PDF:
<!-- HTML结构 -->
<div class="pdf-controls">
  <button id="prev-btn">上一页</button>
  <button id="next-btn">下一页</button>
  <span>第 <span id="current-page">1</span> 页 / 共 <span id="total-pages">0</span> 页</span>
</div>
<canvas id="pdf-canvas"></canvas>

<!-- 引入本地的PDF.js文件 -->
<script src="/path/to/your/pdf.js"></script>
<script src="/path/to/your/pdf.worker.js"></script>
<script>
  // 初始化变量
  let pdfDoc = null;
  let currentPage = 1;
  const scale = 1.5; // 预览缩放比例
  const canvas = document.getElementById('pdf-canvas');
  const ctx = canvas.getContext('2d');

  // 渲染指定页码
  function renderPage(pageNum) {
    pdfDoc.getPage(pageNum).then(page => {
      const viewport = page.getViewport({ scale });
      canvas.height = viewport.height;
      canvas.width = viewport.width;

      // 渲染PDF内容到Canvas
      const renderTask = page.render({
        canvasContext: ctx,
        viewport: viewport
      });

      renderTask.promise.then(() => {
        // 更新页码显示
        document.getElementById('current-page').textContent = pageNum;
      });
    });
  }

  // 加载PDF文件
  pdfjsLib.getDocument('/your-server-path/to/target.pdf').promise.then(pdf => {
    pdfDoc = pdf;
    document.getElementById('total-pages').textContent = pdf.numPages;
    renderPage(currentPage);
  });

  // 绑定分页按钮事件
  document.getElementById('prev-btn').addEventListener('click', () => {
    if (currentPage > 1) {
      currentPage--;
      renderPage(currentPage);
    }
  });

  document.getElementById('next-btn').addEventListener('click', () => {
    if (currentPage < pdfDoc.numPages) {
      currentPage++;
      renderPage(currentPage);
    }
  });
</script>

优缺点

  • ✅ 优点:完全自定义UI和交互,支持分页、缩放、搜索、标注等高级功能,跨浏览器显示一致
  • ❌ 缺点:需要引入额外库,代码量比原生方案多,需要理解基本的Canvas渲染逻辑
方案3:后端转换为图片/HTML(极致兼容)

如果需要兼容非常老旧的浏览器(比如IE10及以下),或者需要对PDF内容做预处理(比如加水印、提取文本),可以在后端把PDF转成图片或者HTML,再返回给前端显示。

实现思路

  • 后端工具选择:
    • Python:用 PyPDF2 + Pillow 转图片,或者 pdf2htmlEX 转HTML
    • Node.js:用 pdf-poppler 转图片,或者 pdf2pic
    • Java:用 iText 或者 Apache PDFBox
  • 前端直接显示生成的图片(循环渲染所有页)或者HTML内容

示例(Node.js转图片)

// 后端Node.js代码
const poppler = require('pdf-poppler');
const fs = require('fs');
const path = require('path');

async function convertPdfToImages(pdfFilePath) {
  const options = {
    format: 'png', // 输出格式可选png/jpg
    out_dir: path.dirname(pdfFilePath),
    out_prefix: path.basename(pdfFilePath, '.pdf'),
    page: null // 转换所有页面,指定数字可转单页
  };

  try {
    await poppler.convert(pdfFilePath, options);
    // 返回生成的图片文件名列表
    return fs.readdirSync(path.dirname(pdfFilePath)).filter(file => 
      file.startsWith(path.basename(pdfFilePath, '.pdf'))
    );
  } catch (err) {
    console.error('PDF转图片失败:', err);
    throw err;
  }
}

优缺点

  • ✅ 优点:兼容性拉满,所有浏览器都能正常显示,支持对PDF内容做预处理
  • ❌ 缺点:转换过程耗时,生成的图片占用存储空间,转HTML可能丢失原PDF的排版格式

内容的提问来源于stack exchange,提问作者Shreya Sheel Sachan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 14:03:12