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

PDF.js渲染部分PDF页面时出现黑色矩形问题求助

问题分析与修复方案

你遇到的黑色矩形遮挡问题,核心是文本层(textLayer)未正确初始化和挂载,加上代码里的几个细节错误导致的。官方示例完整实现了文本层的渲染流程,而你的代码只创建了textLayer元素却没完成后续步骤,部分PDF的特殊文本排版触发了异常。

具体问题点

  1. 创建的textLayer元素未添加到DOM中,也未调用PDF.js的文本层渲染API,导致文本层的占位元素出现异常黑块
  2. canvas.width设置为字符串'600',应该使用数字类型,会干扰渲染比例计算
  3. 缺少文本层必需的CSS样式,官方textLayer类需要特定样式才能正常显示

修复后的代码

修改initPdf函数

function initPdf(url){
    const { pdfjsLib } = globalThis;
    pdfjsLib.GlobalWorkerOptions.workerSrc = 'js/pdfjs/build/pdf.worker.mjs';

    const loadingTask = pdfjsLib.getDocument(url);
    loadingTask.promise.then(function(pdf) {
        const thePdf = pdf;
        const viewer = document.getElementById('pdf-viewer');
        
        for(let page = 1; page <= pdf.numPages; page++) {
          // 用容器包裹canvas和textLayer,保证层级正确
          const pageContainer = document.createElement("div");
          pageContainer.className = 'pdf-page-container';

          const canvas = document.createElement("canvas");
          canvas.id = 'pdfCanvas'+page;
          canvas.className = 'pdf-page-canvas'; 
          canvas.width = 600; // 改为数字类型
          
          const textLayer = document.createElement("div");
          textLayer.id = 'textLayer'+page;     
          textLayer.className = 'textLayer';

          pageContainer.appendChild(canvas);
          pageContainer.appendChild(textLayer);
          viewer.appendChild(pageContainer);
                    
          renderPage(page, canvas, textLayer, thePdf);
        }
        
    });
}

修改renderPage函数

function renderPage(pageNumber, canvas, textLayer, pdf) {
  pdf.getPage(pageNumber).then(function(page) {
    const viewport = page.getViewport({ scale: 1 });
    const scale = canvas.width / viewport.width;
    const scaledViewport = page.getViewport({ scale: scale });
    canvas.height = scaledViewport.height;
    
    const renderContext = {
      canvasContext: canvas.getContext('2d'), 
      viewport: scaledViewport
    };

    // 先渲染画布,再渲染文本层
    const renderTask = page.render(renderContext);
    renderTask.promise.then(function() {
      // 获取文本内容并渲染到文本层
      return page.getTextContent();
    }).then(function(textContent) {
      pdfjsLib.renderTextLayer({
        textContent: textContent,
        container: textLayer,
        viewport: scaledViewport,
        textDivs: []
      });
    });
  });
}

必需的CSS样式

需要添加文本层的基础样式(可从PDF.js官方示例中提取),否则仍可能出现显示异常:

.textLayer {
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  overflow: hidden;
  opacity: 0.2; /* 可根据需求调整,官方默认是0.2,设为0则隐藏文本层 */
  line-height: 1;
}

.textLayer > div {
  color: transparent;
  position: absolute;
  white-space: pre;
  cursor: text;
  transform-origin: 0% 0%;
}

.pdf-page-container {
  position: relative;
  margin-bottom: 10px; /* 页面间距,可调整 */
}

.pdf-page-canvas {
  display: block;
}

额外说明

  • 变量尽量用const/let声明,避免全局变量污染
  • 文本层的opacity可以根据需求调整,如果不需要选中文本功能,也可以直接不渲染文本层(去掉相关代码),但部分PDF的渲染依赖文本层的排版信息,建议保留

内容的提问来源于stack exchange,提问作者Roldan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 08:06:06