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

Django中使用pdf.js生成PDF第一页预览仅首个生效如何解决

问题根因

HTML规范要求页面内元素ID全局唯一,你在{% for %}循环中给所有canvas和json_script元素都设置了固定的the-canvas、mydataID,JS调用getElementById时只会返回匹配到的第一个元素,因此只有第一个PDF能正常渲染预览。

修复方案

第一步:修改pdf_lists.htm模板

将固定ID改为动态标识,或者直接把PDF路径存放到canvas的自定义属性中,简化后续JS逻辑:

{% for obj in pdfs %}
    <tr>
         <td>{{ forloop.counter }}</td>
         <td>
             <a href="{{ obj.docfile.url }}" target="_blank" rel="noopener noreferrer">{{obj.filename}}</a>
         </td>
         <td>{{ obj.uploaded_at|date:"d-M-Y" }}</td>
         <td>
             <a href="{{obj.docfile.url}}" target="_blank" rel="noopener noreferrer">
                 <!-- 增加公共类名和存储PDF路径的自定义属性,去掉固定ID -->
                 <canvas class="pdf-preview-canvas" data-pdf-url="{{ obj.docfile.url }}" style="height:250px;"></canvas>
             </a>
         </td>
    </tr>
{% endfor %}

第二步:修改pdf.js逻辑

改为遍历所有预览canvas,逐个渲染PDF:

// 全局仅配置一次worker路径
pdfjsLib.GlobalWorkerOptions.workerSrc = '//mozilla.github.io/pdf.js/build/pdf.worker.js';

// 遍历所有PDF预览画布,逐个渲染
document.querySelectorAll('.pdf-preview-canvas').forEach(canvas => {
    const pdfUrl = canvas.dataset.pdfUrl;
    const loadingTask = pdfjsLib.getDocument(pdfUrl);
    loadingTask.promise.then(pdf => {
        // 加载第一页
        return pdf.getPage(1);
    }).then(page => {
        const scale = 0.5;
        const viewport = page.getViewport({ scale: scale });
        const context = canvas.getContext('2d');
        canvas.height = viewport.height;
        canvas.width = viewport.width;
        // 渲染到当前画布
        page.render({
            canvasContext: context,
            viewport: viewport
        });
    }).catch(err => {
        console.error('PDF预览加载失败', pdfUrl, err);
    });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 15:15:04