吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1613|回复: 28
收起左侧

[其他转载] 发票批量排版打印在A4纸75%大小

  [复制链接]
wwwwtw 发表于 2026-6-23 10:13
白嫖好多年了,因工作需要,找了一圈没有找到合适的工具,一般的工具都是打印在A4的上半部和整页,我想打印成第三种样式,方便打胶粘贴等,未找到相关工具。

ScreenShot_2026-06-23_095839_220.png

用AI写了个powershell,达到了第三种样式的目的,但是需要借助SumatraPDF.exe,可自行去官网下载,(此处使用SumatraPDF-3.6.1-64.exe做演示,第八行请自行更换SumatraPDF的路径)

AI生成,自行检测代码安全性。


使用方法:
配置好SumatraPDF的路径,将以下代码用记事本保存为【xxx.ps1】格式,初次运行可能会提示什么不受信任的powershell脚本,很简单,自行解决,打开后会弹出pdf选择界面,选择你需要打印的pdf发票(可多选),会自动排版打印成上图的第三种格式,有需要的自取。

附SumatraPDF-3.6.1-64.exe链接,或自行去官网下载。
https://wwbpe.lanzouq.com/iFuiY3sp5o3e


[Shell] 纯文本查看 复制代码
# PDF自动打印脚本 - 使用SumatraPDF直接缩放打印
param(
    [Parameter(Mandatory=$false)]
    [string[]]$FileList
)

# SumatraPDF路径
$sumatraPath = "E:\批量发票打印\SumatraPDF-3.6.1-64.exe"

# 打印缩放比例(可修改:70, 75, 80)
# 70% = 留边距约30%,75% = 留边距约25%,80% = 留边距约20%
$printScale = 75

# 如果没有通过参数传递文件,则弹出文件选择窗口
if (-not $FileList -or $FileList.Count -eq 0) {
    Add-Type -AssemblyName System.Windows.Forms
    $openFileDialog = New-Object System.Windows.Forms.OpenFileDialog
    $openFileDialog.Title = "选择要打印的PDF文件"
    $openFileDialog.Multiselect = $true
    $openFileDialog.Filter = "PDF文件 (*.pdf)|*.pdf|所有文件 (*.*)|*.*"
    
    if ($openFileDialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
        $FileList = $openFileDialog.FileNames
    } else {
        Write-Host "未选择任何文件,程序退出。" -ForegroundColor Yellow
        Read-Host "按回车键退出"
        exit
    }
}

# 检查SumatraPDF是否存在
if (-not (Test-Path $sumatraPath)) {
    Write-Host "错误: 找不到 SumatraPDF.exe" -ForegroundColor Red
    Write-Host "当前路径: $sumatraPath" -ForegroundColor Yellow
    Read-Host "按回车键退出"
    exit
}

# 获取默认打印机
$defaultPrinter = (Get-WmiObject -Class Win32_Printer | Where-Object {$_.Default -eq $true}).Name
Write-Host "默认打印机: $defaultPrinter" -ForegroundColor Green

Write-Host "============================================================" -ForegroundColor Cyan
Write-Host "开始打印 PDF 文件" -ForegroundColor Cyan
Write-Host "打印设置: 缩放 ${printScale}% | 自动居中 | 纵向" -ForegroundColor Yellow
Write-Host "说明: ${printScale}% 表示打印出来的大小是原发票的 ${printScale}%" -ForegroundColor White
Write-Host "      剩余 ${$($null=100-$printScale)}% 为页边距空间" -ForegroundColor White
Write-Host "============================================================" -ForegroundColor Cyan

$successCount = 0
$failCount = 0

foreach ($file in $FileList) {
    if (Test-Path $file) {
        $fileName = Split-Path $file -Leaf
        Write-Host "`n打印: $fileName" -ForegroundColor White
        
        # 直接使用缩放参数,不依赖自定义纸张
        # scaling=XX 直接控制打印大小
        # center=true 自动居中
        # orientation=portrait 纵向打印
        $printArgs = @(
            "-print-to-default"
            "-print-settings", "scaling=$printScale,center=true,orientation=portrait"
            "`"$file`""
        )
        
        Write-Host "  缩放比例: ${printScale}%" -ForegroundColor Gray
        
        try {
            $process = Start-Process -FilePath $sumatraPath -ArgumentList $printArgs -Wait -NoNewWindow -PassThru
            if ($process.ExitCode -eq 0) {
                Write-Host "✓ 打印成功: $fileName" -ForegroundColor Green
                $successCount++
            } else {
                Write-Host "✗ 打印失败: $fileName (退出代码: $($process.ExitCode))" -ForegroundColor Red
                $failCount++
            }
        } catch {
            Write-Host "✗ 打印出错: $fileName - $_" -ForegroundColor Red
            $failCount++
        }
    } else {
        Write-Host "文件不存在: $file" -ForegroundColor Red
        $failCount++
    }
}

Write-Host "`n============================================================" -ForegroundColor Cyan
Write-Host "打印完成!" -ForegroundColor Cyan
Write-Host "成功: $successCount | 失败: $failCount" -ForegroundColor White
Write-Host "============================================================" -ForegroundColor Cyan
Write-Host "提示: 如需调整大小,请修改脚本第12行的 `$printScale 值" -ForegroundColor Yellow
Write-Host "      70=较小边距大 | 75=适中 | 80=较大边距小" -ForegroundColor Yellow

#Read-Host "`n按回车键退出"

免费评分

参与人数 3吾爱币 +4 热心值 +3 收起 理由
苏紫方璇 + 2 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
wanfon + 1 + 1 热心回复!
grrr_zhao + 1 + 1 谢谢@Thanks!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

jiarenlu 发表于 2026-6-23 11:31
都已经ai了为什么不直接写个工具
ScreenShot_2026-06-23_112955_915.png 93dc2961-454c-4bad-9ad5-50b99a10f1fa.png
[HTML] 纯文本查看 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>批量打印PDF发票</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.min.js"></script>
    <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@300;400;500;700&family=Playfair+Display:wght@600&display=swap" rel="stylesheet">
    <style>
        :root {
            --primary: #1a365d;
            --primary-light: #2c5282;
            --accent: #ed8936;
            --accent-light: #f6ad55;
            --bg: #f7fafc;
            --card-bg: #ffffff;
            --text: #2d3748;
            --text-light: #718096;
            --border: #e2e8f0;
            --success: #38a169;
            --danger: #e53e3e;
            --shadow: 0 10px 40px rgba(26, 54, 93, 0.1);
            --shadow-hover: 0 20px 60px rgba(26, 54, 93, 0.15);
        }

        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: 'Noto Sans SC', sans-serif;
            background: var(--bg);
            color: var(--text);
            min-height: 100vh;
            background-image: 
                radial-gradient(circle at 20% 50%, rgba(237, 137, 54, 0.05) 0%, transparent 50%),
                radial-gradient(circle at 80% 20%, rgba(26, 54, 93, 0.05) 0%, transparent 50%),
                radial-gradient(circle at 40% 80%, rgba(44, 82, 130, 0.03) 0%, transparent 40%);
        }

        .container {
            max-width: 1400px;
            margin: 0 auto;
            padding: 40px 20px;
        }

        header {
            text-align: center;
            margin-bottom: 50px;
            animation: fadeInDown 0.8s ease-out;
        }

        @keyframes fadeInDown {
            from {
                opacity: 0;
                transform: translateY(-30px);
            }
            to {
                opacity: 1;
                transform: translateY(0);
            }
        }

        h1 {
            font-family: 'Playfair Display', serif;
            font-size: 3rem;
            font-weight: 600;
            color: var(--primary);
            margin-bottom: 12px;
            letter-spacing: -0.02em;
        }

        .subtitle {
            color: var(--text-light);
            font-size: 1.1rem;
            font-weight: 300;
        }

        .toolbar {
            display: flex;
            gap: 16px;
            justify-content: center;
            flex-wrap: wrap;
            margin-bottom: 40px;
            animation: fadeIn 0.8s ease-out 0.2s both;
        }

        @keyframes fadeIn {
            from { opacity: 0; }
            to { opacity: 1; }
        }

        .btn {
            padding: 14px 32px;
            border: none;
            border-radius: 12px;
            font-size: 1rem;
            font-weight: 500;
            cursor: pointer;
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
            display: inline-flex;
            align-items: center;
            gap: 10px;
            font-family: inherit;
        }

        .btn-primary {
            background: linear-gradient(135deg, var(--primary) 0%, var(--primary-light) 100%);
            color: white;
            box-shadow: 0 4px 15px rgba(26, 54, 93, 0.3);
        }

        .btn-primary:hover {
            transform: translateY(-2px);
            box-shadow: 0 8px 25px rgba(26, 54, 93, 0.4);
        }

        .btn-accent {
            background: linear-gradient(135deg, var(--accent) 0%, var(--accent-light) 100%);
            color: white;
            box-shadow: 0 4px 15px rgba(237, 137, 54, 0.3);
        }

        .btn-accent:hover {
            transform: translateY(-2px);
            box-shadow: 0 8px 25px rgba(237, 137, 54, 0.4);
        }

        .btn-secondary {
            background: var(--card-bg);
            color: var(--text);
            border: 2px solid var(--border);
        }

        .btn-secondary:hover {
            border-color: var(--primary);
            color: var(--primary);
        }

        .btn:disabled {
            opacity: 0.5;
            cursor: not-allowed;
            transform: none !important;
        }

        .btn svg {
            width: 20px;
            height: 20px;
        }

        .stats {
            display: flex;
            justify-content: center;
            gap: 40px;
            margin-bottom: 40px;
            animation: fadeIn 0.8s ease-out 0.3s both;
        }

        .stat-item {
            text-align: center;
        }

        .stat-value {
            font-size: 2.5rem;
            font-weight: 700;
            color: var(--primary);
            line-height: 1;
        }

        .stat-label {
            color: var(--text-light);
            font-size: 0.9rem;
            margin-top: 8px;
        }

        /* 上传区域 */
        .upload-zone {
            background: var(--card-bg);
            border: 3px dashed var(--border);
            border-radius: 20px;
            padding: 60px 40px;
            text-align: center;
            margin-bottom: 40px;
            transition: all 0.3s ease;
            cursor: pointer;
            animation: fadeIn 0.8s ease-out 0.4s both;
        }

        .upload-zone:hover,
        .upload-zone.dragover {
            border-color: var(--accent);
            background: rgba(237, 137, 54, 0.05);
        }

        .upload-zone.dragover {
            transform: scale(1.02);
        }

        .upload-icon {
            width: 80px;
            height: 80px;
            margin: 0 auto 20px;
            color: var(--text-light);
            opacity: 0.6;
        }

        .upload-title {
            font-size: 1.4rem;
            font-weight: 600;
            color: var(--text);
            margin-bottom: 10px;
        }

        .upload-hint {
            color: var(--text-light);
            font-size: 0.95rem;
        }

        .upload-hint span {
            color: var(--accent);
            font-weight: 500;
        }

        #fileInput {
            display: none;
        }

        /* PDF列表 */
        .pdf-grid {
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
            gap: 24px;
            animation: fadeIn 0.8s ease-out 0.5s both;
        }

        .pdf-card {
            background: var(--card-bg);
            border-radius: 16px;
            overflow: hidden;
            box-shadow: var(--shadow);
            transition: all 0.3s ease;
            position: relative;
        }

        .pdf-card:hover {
            transform: translateY(-4px);
            box-shadow: var(--shadow-hover);
        }

        .pdf-preview {
            width: 100%;
            background: #f0f0f0;
            display: flex;
            align-items: center;
            justify-content: center;
            position: relative;
            padding: 12px;
            min-height: 220px;
        }

        .pdf-preview img {
            width: 100%;
            height: auto;
            display: block;
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
        }

        .pdf-preview canvas {
            width: 100%;
            height: auto;
            display: block;
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
        }

        .pdf-preview .loading {
            color: var(--text-light);
            font-size: 0.9rem;
        }

        .pdf-badge {
            position: absolute;
            top: 10px;
            right: 10px;
            background: var(--danger);
            color: white;
            padding: 4px 10px;
            border-radius: 20px;
            font-size: 0.75rem;
            font-weight: 600;
        }

        .pdf-info {
            padding: 16px;
        }

        .pdf-name {
            font-weight: 600;
            color: var(--text);
            margin-bottom: 8px;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            font-size: 0.95rem;
        }

        .pdf-meta {
            display: flex;
            justify-content: space-between;
            color: var(--text-light);
            font-size: 0.85rem;
        }

        .pdf-actions {
            display: flex;
            gap: 8px;
            padding: 12px 16px;
            border-top: 1px solid var(--border);
        }

        .btn-small {
            padding: 8px 14px;
            font-size: 0.85rem;
            border-radius: 8px;
            flex: 1;
        }

        .btn-delete {
            background: transparent;
            color: var(--danger);
            border: 1px solid #fed7d7;
        }

        .btn-delete:hover {
            background: #fff5f5;
            border-color: #fc8181;
        }

        .empty-state {
            text-align: center;
            padding: 80px 20px;
            color: var(--text-light);
            grid-column: 1 / -1;
        }

        .empty-icon {
            font-size: 4rem;
            margin-bottom: 20px;
            opacity: 0.5;
        }

        /* 打印样式 */
        [url=home.php?mod=space&uid=945662]@media[/url] print {
            body {
                background: white;
            }

            .container,
            .toolbar,
            .stats,
            header,
            .upload-zone,
            .pdf-grid,
            .no-print {
                display: none !important;
            }

            .print-container {
                display: block !important;
            }

            .print-page {
                page-break-after: always;
                page-break-inside: avoid;
                width: 297mm;
                height: 210mm;
                display: flex;
                align-items: center;
                justify-content: center;
                padding: 0;
                margin: 0;
                box-sizing: border-box;
                background: white;
            }

            .print-page:last-child {
                page-break-after: auto;
            }

            .print-invoice {
                width: 75%;
                height: 75%;
                display: flex;
                align-items: center;
                justify-content: center;
            }

            .print-invoice img,
            .print-invoice canvas {
                max-width: 100%;
                max-height: 100%;
                object-fit: contain;
            }

            [url=home.php?mod=space&uid=1953840]@page[/url] {
                size: A4 landscape;
                margin: 0;
            }
        }

        .print-container {
            display: none;
        }

        /* 进度条 */
        .progress-bar {
            width: 100%;
            height: 4px;
            background: var(--border);
            border-radius: 2px;
            overflow: hidden;
            margin-top: 10px;
        }

        .progress-fill {
            height: 100%;
            background: linear-gradient(90deg, var(--primary), var(--accent));
            transition: width 0.3s ease;
        }

        /* 响应式 */
        @media (max-width: 768px) {
            h1 {
                font-size: 2rem;
            }

            .stats {
                gap: 20px;
            }

            .stat-value {
                font-size: 2rem;
            }

            .pdf-grid {
                grid-template-columns: 1fr;
            }

            .upload-zone {
                padding: 40px 20px;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <header>
            <h1>发票批量打印</h1>
            <p class="subtitle">上传PDF发票原件,一键批量打印</p>
        </header>

        <div class="toolbar">
            <button class="btn btn-primary">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                    <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
                    <polyline points="17 8 12 3 7 8"></polyline>
                    <line x1="12" y1="3" x2="12" y2="15"></line>
                </svg>
                上传PDF发票
            </button>
            <button class="btn btn-accent" id="printAllBtn" disabled>
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                    <polyline points="6 9 6 2 18 2 18 9"></polyline>
                    <path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"></path>
                    <rect x="6" y="14" width="12" height="8"></rect>
                </svg>
                批量打印
            </button>
            <button class="btn btn-secondary">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                    <polyline points="3 6 5 6 21 6"></polyline>
                    <path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path>
                </svg>
                清空全部
            </button>
        </div>

        <div class="stats">
            <div class="stat-item">
                <div class="stat-value" id="pdfCount">0</div>
                <div class="stat-label">发票数量</div>
            </div>
            <div class="stat-item">
                <div class="stat-value" id="totalPages">0</div>
                <div class="stat-label">总页数</div>
            </div>
        </div>

        <div class="upload-zone" id="uploadZone">
            <svg class="upload-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
                <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path>
                <polyline points="14 2 14 8 20 8"></polyline>
                <line x1="12" y1="18" x2="12" y2="12"></line>
                <line x1="9" y1="15" x2="15" y2="15"></line>
            </svg>
            <div class="upload-title">点击或拖拽上传PDF发票</div>
            <div class="upload-hint">支持 <span>批量上传</span> 多个PDF文件</div>
        </div>

        <input type="file" id="fileInput" accept=".pdf" multiple>

        <div class="pdf-grid" id="pdfGrid">
            <div class="empty-state" id="emptyState">
                <div class="empty-icon">&#128196;</div>
                <p>暂无发票,请上传PDF文件</p>
            </div>
        </div>
    </div>

    <!-- 打印区域 -->
    <div class="print-container" id="printContainer"></div>

    <script>
        // 设置PDF.js worker
        pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.js';

        // PDF文件存储
        let pdfFiles = [];

        // 初始化
        document.addEventListener('DOMContentLoaded', function () {
            setupDragDrop();
        });

        // 设置拖拽上传
        function setupDragDrop() {
            const uploadZone = document.getElementById('uploadZone');

            ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
                uploadZone.addEventListener(eventName, preventDefaults, false);
            });

            function preventDefaults(e) {
                e.preventDefault();
                e.stopPropagation();
            }

            ['dragenter', 'dragover'].forEach(eventName => {
                uploadZone.addEventListener(eventName, () => {
                    uploadZone.classList.add('dragover');
                }, false);
            });

            ['dragleave', 'drop'].forEach(eventName => {
                uploadZone.addEventListener(eventName, () => {
                    uploadZone.classList.remove('dragover');
                }, false);
            });

            uploadZone.addEventListener('drop', handleDrop, false);
        }

        // 处理拖拽文件
        function handleDrop(e) {
            const dt = e.dataTransfer;
            const files = dt.files;
            handleFiles(files);
        }

        // 文件选择处理
        document.getElementById('fileInput').addEventListener('change', function (e) {
            handleFiles(e.target.files);
            e.target.value = ''; // 清空以允许重复选择相同文件
        });

        // 处理文件
        async function handleFiles(files) {
            const pdfFilesArray = Array.from(files).filter(file => file.type === 'application/pdf');

            if (pdfFilesArray.length === 0) {
                alert('请选择PDF文件');
                return;
            }

            for (const file of pdfFilesArray) {
                await addPDFFile(file);
            }
        }

        // 添加PDF文件
        async function addPDFFile(file) {
            const id = Date.now() + Math.random();
            const pdfData = {
                id: id,
                name: file.name,
                size: file.size,
                file: file,
                pageCount: 0,
                preview: null,
                pdfDoc: null
            };

            pdfFiles.push(pdfData);
            renderPDFList();

            // 读取PDF
            try {
                const arrayBuffer = await file.arrayBuffer();
                const pdf = await pdfjsLib.getDocument({ data: arrayBuffer }).promise;
                pdfData.pageCount = pdf.numPages;
                pdfData.pdfDoc = pdf;

                // 生成预览 - 使用更高清晰度,完整显示发票
                const page = await pdf.getPage(1);
                const scale = 2;
                const viewport = page.getViewport({ scale: scale });

                const canvas = document.createElement('canvas');
                const context = canvas.getContext('2d');
                canvas.width = viewport.width;
                canvas.height = viewport.height;

                await page.render({
                    canvasContext: context,
                    viewport: viewport
                }).promise;

                pdfData.preview = canvas.toDataURL('image/jpeg', 0.9);
                renderPDFList();
                updateStats();
            } catch (error) {
                console.error('PDF读取失败:', error);
                alert(`文件 "${file.name}" 读取失败,请确保是有效的PDF文件`);
                pdfFiles = pdfFiles.filter(p => p.id !== id);
                renderPDFList();
            }
        }

        // 渲染PDF列表
        function renderPDFList() {
            const grid = document.getElementById('pdfGrid');

            if (pdfFiles.length === 0) {
                grid.innerHTML = `
                    <div class="empty-state" id="emptyState">
                        <div class="empty-icon">&#128196;</div>
                        <p>暂无发票,请上传PDF文件</p>
                    </div>
                `;
                document.getElementById('printAllBtn').disabled = true;
            } else {
                document.getElementById('printAllBtn').disabled = false;

                grid.innerHTML = pdfFiles.map(pdf => `
                    <div class="pdf-card" data-id="${pdf.id}">
                        <div class="pdf-preview">
                            ${pdf.preview
                        ? `<img src="${pdf.preview}" alt="${pdf.name}">`
                        : '<div class="loading">加载中...</div>'
                    }
                            <span class="pdf-badge">PDF</span>
                        </div>
                        <div class="pdf-info">
                            <div class="pdf-name" title="${pdf.name}">${pdf.name}</div>
                            <div class="pdf-meta">
                                <span>${formatFileSize(pdf.size)}</span>
                                <span>${pdf.pageCount > 0 ? pdf.pageCount + '页' : '读取中...'}</span>
                            </div>
                        </div>
                        <div class="pdf-actions">
                            <button class="btn btn-small btn-secondary">打印预览</button>
                            <button class="btn btn-small btn-delete">删除</button>
                        </div>
                    </div>
                `).join('');
            }

            updateStats();
        }

        // 更新统计
        function updateStats() {
            document.getElementById('pdfCount').textContent = pdfFiles.length;
            const totalPages = pdfFiles.reduce((sum, pdf) => sum + pdf.pageCount, 0);
            document.getElementById('totalPages').textContent = totalPages;
        }

        // 格式化文件大小
        function formatFileSize(bytes) {
            if (bytes === 0) return '0 B';
            const k = 1024;
            const sizes = ['B', 'KB', 'MB', 'GB'];
            const i = Math.floor(Math.log(bytes) / Math.log(k));
            return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
        }

        // 删除PDF
        function removePDF(id) {
            pdfFiles = pdfFiles.filter(pdf => pdf.id !== id);
            renderPDFList();
        }

        // 清空所有PDF
        function clearAllPDFs() {
            if (pdfFiles.length === 0) return;
            if (confirm('确定要清空所有PDF文件吗?')) {
                pdfFiles = [];
                renderPDFList();
            }
        }

        // 打印预览PDF
        async function previewPDF(id) {
            const pdfData = pdfFiles.find(p => p.id === id);
            if (!pdfData || !pdfData.pdfDoc) return;

            const printContainer = document.getElementById('printContainer');
            printContainer.innerHTML = '';

            // 渲染PDF所有页面到打印容器,横向A4 75%显示
            for (let i = 1; i <= pdfData.pageCount; i++) {
                const page = await pdfData.pdfDoc.getPage(i);

                // A4横向: 297mm x 210mm, 75%大小
                const a4Width = 297 * 0.75;
                const a4Height = 210 * 0.75;

                // 获取PDF页面尺寸(以点为单位,1点 = 1/72英寸)
                const pdfWidth = page.view[2];
                const pdfHeight = page.view[3];

                // 计算缩放比例以适应75%的A4横向尺寸
                const targetWidthPt = a4Width * 2.83;
                const targetHeightPt = a4Height * 2.83;

                const scaleX = targetWidthPt / pdfWidth;
                const scaleY = targetHeightPt / pdfHeight;
                const scale = Math.min(scaleX, scaleY) * 1.5;

                const viewport = page.getViewport({ scale: scale });

                const canvas = document.createElement('canvas');
                const context = canvas.getContext('2d');
                canvas.width = viewport.width;
                canvas.height = viewport.height;

                await page.render({
                    canvasContext: context,
                    viewport: viewport
                }).promise;

                const pageDiv = document.createElement('div');
                pageDiv.className = 'print-page';

                const invoiceDiv = document.createElement('div');
                invoiceDiv.className = 'print-invoice';

                const img = document.createElement('img');
                img.src = canvas.toDataURL('image/png');
                invoiceDiv.appendChild(img);
                pageDiv.appendChild(invoiceDiv);
                printContainer.appendChild(pageDiv);
            }

            // 触发打印
            setTimeout(() => {
                window.print();
            }, 500);
        }

        // 批量打印所有PDF
        async function printAllPDFs() {
            if (pdfFiles.length === 0) {
                alert('没有可打印的PDF文件');
                return;
            }

            // 检查是否所有PDF都已加载完成
            const unloadedPDFs = pdfFiles.filter(pdf => !pdf.pdfDoc);
            if (unloadedPDFs.length > 0) {
                alert('部分PDF文件仍在加载中,请稍候...');
                return;
            }

            const printContainer = document.getElementById('printContainer');
            printContainer.innerHTML = '';

            // 渲染所有PDF的所有页面
            for (const pdfData of pdfFiles) {
                for (let i = 1; i <= pdfData.pageCount; i++) {
                    const page = await pdfData.pdfDoc.getPage(i);

                    // A4横向: 297mm x 210mm, 75%大小
                    const a4Width = 297 * 0.75;
                    const a4Height = 210 * 0.75;

                    // 获取PDF页面尺寸(以点为单位,1点 = 1/72英寸)
                    const pdfWidth = page.view[2];
                    const pdfHeight = page.view[3];

                    // 计算缩放比例以适应75%的A4横向尺寸
                    // 1mm ≈ 2.83点
                    const targetWidthPt = a4Width * 2.83;
                    const targetHeightPt = a4Height * 2.83;

                    const scaleX = targetWidthPt / pdfWidth;
                    const scaleY = targetHeightPt / pdfHeight;
                    const scale = Math.min(scaleX, scaleY) * 1.5;
                    
                    const viewport = page.getViewport({ scale: scale });

                    const canvas = document.createElement('canvas');
                    const context = canvas.getContext('2d');
                    canvas.width = viewport.width;
                    canvas.height = viewport.height;

                    await page.render({
                        canvasContext: context,
                        viewport: viewport
                    }).promise;

                    const pageDiv = document.createElement('div');
                    pageDiv.className = 'print-page';
                    
                    const invoiceDiv = document.createElement('div');
                    invoiceDiv.className = 'print-invoice';
                    
                    const img = document.createElement('img');
                    img.src = canvas.toDataURL('image/png');
                    invoiceDiv.appendChild(img);
                    pageDiv.appendChild(invoiceDiv);
                    printContainer.appendChild(pageDiv);
                }
            }

            // 触发打印
            setTimeout(() => {
                window.print();
            }, 500);
        }
    </script>
</body>
</html>

免费评分

参与人数 2吾爱币 +2 热心值 +2 收起 理由
abao117 + 1 + 1 谢谢@Thanks!
shaunkelly + 1 + 1 我很赞同!

查看全部评分

wuy009 发表于 2026-6-23 16:51
我个人对比了一下,觉得最方便的A4纸打印发票还是2345看图王11往后的版本,其中附带的pdf发票打印功能,能设置在一张A4纸打印两张甚至四张发票,还是相当方便。当然这涉及三个问题,一是2345看图王得用去广告版,二是看图王的版本必须是11.3往后,三是只适应A4纸而不是A5纸打印发票。个人意见,仅供参考。
sunflash 发表于 2026-6-23 10:40
wyl0205 发表于 2026-6-23 11:16
sunflash 发表于 2026-6-23 10:40
打印,选实际大小,居中。不能实现吗?

正解,哪个能打开pdf的应该都能实现
helh0275 发表于 2026-6-23 11:28
word文档中贴图,拖动大小不就可以一页打多张吗
逐雅斋 发表于 2026-6-23 11:29
感谢分享!
pi911 发表于 2026-6-23 11:31
本帖最后由 pi911 于 2026-6-23 11:32 编辑

Adobe Acrobat多页打印,A4打印2张或者3张
wojaiyh 发表于 2026-6-23 12:20
我目前用这个  多张发票一起打  A5纸  
很方便~!https://www.52pojie.cn/forum.php ... hlight=%B7%A2%C6%B1
Amo52 发表于 2026-6-23 12:29
发票不都是用A5么。
wojaiyh 发表于 2026-6-23 12:51
本帖最后由 wojaiyh 于 2026-6-23 13:07 编辑
Amo52 发表于 2026-6-23 12:29
发票不都是用A5么。

我们单位发票打印都是A5
应该是方便财务装订吧

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-7-10 19:28

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表