如何用一张 A4 纸,打印多张 PDF 电子发票,用来报销

原始链接在: 如何用一张 A4 纸,打印多张 PDF 电子发票,用来报销 - 小众软件

昨天在群里有同学提出了这个问题:需要将多张电子发票打印出来,用来报销。

经过在群里和微博的讨论之后,很多同学都给出了解决方案,比较靠谱的流程是:

  1. 将多个 PDF 文档合并为一个
  2. 利用打印机自带的一张多页功能完成打印

合并 PDF 文档

这其中也遇到了不少问题,比较典型的就是很多软件在合并带有「加密电子签名」公章的发票 PDF 之后,会导致公章丢失。

虽然可以用截图的方式来解决这个问题,但有没有更优雅的解决方案呢?

PDF Arranger – 免费的 PDF 分割、PDF 合并、旋转等 8 功能工具[Windows/Linux]

这是个免费、开源的 PDF 工具,简单易用。

青小蛙尝试将来自京东的电子发票,以及另外一张电子发票合并,保存的新文件包含来完整的内容。虽然在保存的时候,PDF Arranger 的确提到了可能会丢失部分内容,但又没有真的丢失 😂

使用简单,直接将多个 PDF 拖进 PDF Arranger 里面,然后点击左上角的第三个按钮,就可以保存为新的 PDF 文件了。

一张多页打印 PDF 文件

基本上每一款软件都带有「一张多页」功能:

这样,就可以让打印机自动将一个 PDF 的多页内容合并到一起打印了。

一条龙解决方案

还有微博的 @Gacgle 同学提供了一个软件:PDF-XChange(收费软件)就可以。不用全部合并,首先用它打开所有PDF,然后选打印全部,然后在打印设置里选打印的版式就行。我就经常这样做。[doge]

另外,在 Mac 下也可使用预览功能,将多个 PDF 直接拖到一起,就可以打印了。


实际上还有更专业的软件,直接全部给他,不用操作直接打印就行了。但青小蛙觉得完全没必要再找一款软件了,除非你经常需要这样做,否则现有方法,一个月一两次足够用了。

原文:https://www.appinn.com/how-to-print-pdf-invoices/

感谢 #4001 各位同学的电子,就不一一点名了。

2 个赞

PriPrinter

一个打印机工具, 会生成一个虚拟打印机.

可以直接缩放打印.

priPrinter 是一个虚拟打印机和打印预览程序,可以按照您希望的方式打印文档。使用priPrinter, 您可以直接在屏幕上查看和修改真实的纸张,而无需打印。您可以自由删除或重新排列页面、调整页边距、将多个页面放在一张纸上、更正或编辑文本、应用水印。只需点击几下鼠标,您就可以创建小册子、海报、信笺。

最后,您可以以单面或双面模式将作业打印到真实打印机,保存为 PDF 或图像文件。打印历史记录可用且易于使用,允许检查或重新打印以前打印的文档。您可以在所有文档中搜索任何单词或短语。

每个功能都经过精心设计,例如:您可以使用鼠标拖动边距或输入精确值、创建新水印或使用现有水印、以经典一页模式甚至3D 模式查看页面。您可以使用priPrinter 将常用的布局和设置保存到配置文件中。

而且还可以实现类似格式转换的功能. 毕竟有些发票格式是ofd 格式.

2 个赞

这个我会,来自52pj
发票闪印

最简单也最常用的方式还是用WPS的发票打印功能吧,免费的

这个工具也挺方便的
PDFPatcher

非常好用的在线工具,可以批量上传,并选择一张纸分几个区。
这是公司财务给我们教的方法。

1 个赞

有没有类似的免费软件?这种可以选份数批量打印的,比pdf合并工具方便多了,那些合并工具基本都没怎么考虑一个文件重复多次的情况

我查了一下,最接近的免费软件就是这个

PDF-XChange(收费软件)

PDF-XChange Editor 这个免费版就支持打印全部的功能。

这个章不重要啊,有些公司开出来的电子票都没有章呢,为什么一定要有章啊我不明白(来自一名财务的困惑)

财务不说,普通报销人员不懂啊,以为不带章这个发票就不起作用,所以就怕报销的时候不管用的

报销不一定要四张票,最简单是买A5的纸就好。带菜单或明细单的直接双面A5

站内搜索了下,发现这个还挺好用的

发票也就是一张A5幅面吧,太小了内容不清楚了呀,虽然只是象征性的。

PDF-XChange官方从22年7月开始停止一切在中国大陆和香港地区的销售了,人家不卖给你。

这软件前两天刚被我删了,目前就是保留了PDFPatcher和PDF文件处理助手这两个,在线应用也筛选了2个备用

之前为了一张a4能打两张发票出来还真搞过类似的东西

import tkinter as tk
from tkinter import filedialog
import fitz  # PyMuPDF
from PIL import Image
import tempfile

def select_files():
    root = tk.Tk()
    root.withdraw()  # Hide the root window
    file_paths = filedialog.askopenfilenames(filetypes=[("PDF files", "*.pdf")])
    return file_paths

def convert_pdf_to_image(pdf_path, page_num, output_image_path, dpi=300):
    doc = fitz.open(pdf_path)
    page = doc.load_page(page_num)
    mat = fitz.Matrix(dpi / 72, dpi / 72)  # Scale the page to the desired DPI
    pix = page.get_pixmap(matrix=mat, alpha=False)
    pix.save(output_image_path)
    return pix.width, pix.height

def crop_image(image_path):
    img = Image.open(image_path)
    bbox = img.getbbox()  # Get bounding box of the non-white areas
    if bbox:
        img_cropped = img.crop(bbox)
        img_cropped.save(image_path)
    img.close()  # Ensure the file is closed
    return image_path

def merge_pdfs_to_new_pdf(pdf_paths, output_pdf_path):
    with tempfile.TemporaryDirectory() as temp_dir:
        images = []
        
        for idx, pdf_path in enumerate(pdf_paths):
            image_path = f"{temp_dir}/page{idx}.jpg"
            convert_pdf_to_image(pdf_path, 0, image_path, dpi=300)
            crop_image(image_path)
            images.append(image_path)
        
        a4_width_px = int(210 / 25.4 * 300)
        a4_height_px = int(297 / 25.4 * 300)
        gap_px = int(1 / 2.54 * 300)  # 1 cm gap
        max_width = a4_width_px - int(1 / 2.54 * 300) * 2  # 1 cm margin on each side
        
        merged_images = []
        
        for i in range(0, len(images), 2):
            img1 = Image.open(images[i])
            img1 = img1.resize((max_width, int(img1.height * max_width / img1.width)), Image.LANCZOS)
            
            if i + 1 < len(images):
                img2 = Image.open(images[i + 1])
                img2 = img2.resize((max_width, int(img2.height * max_width / img2.width)), Image.LANCZOS)
            else:
                img2 = Image.new('RGB', (max_width, img1.height), (255, 255, 255))  # Create a blank image if odd number of PDFs
            
            merged_image = Image.new('RGB', (a4_width_px, a4_height_px), (255, 255, 255))
            
            y_offset1 = (a4_height_px - img1.height - img2.height - gap_px) // 2
            y_offset2 = y_offset1 + img1.height + gap_px
            
            merged_image.paste(img1, (int((a4_width_px - max_width) / 2), y_offset1))
            merged_image.paste(img2, (int((a4_width_px - max_width) / 2), y_offset2))
            
            img1.close()
            img2.close()
            
            merged_images.append(merged_image)
        
        merged_images[0].save(output_pdf_path, "PDF", resolution=300.0, save_all=True, append_images=merged_images[1:])

def main():
    files = select_files()
    if len(files) >= 2:
        output_pdf_path = "output.pdf"
        merge_pdfs_to_new_pdf(files, output_pdf_path)
        print(f"PDF created: {output_pdf_path}")
    else:
        print("Please select at least two PDF files.")

if __name__ == "__main__":
    main()