原始链接在: 如何用一张 A4 纸,打印多张 PDF 电子发票,用来报销 - 小众软件
昨天在群里有同学提出了这个问题:需要将多张电子发票打印出来,用来报销。
经过在群里和微博的讨论之后,很多同学都给出了解决方案,比较靠谱的流程是:
- 将多个 PDF 文档合并为一个
- 利用打印机自带的一张多页功能完成打印
合并 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 个赞
最简单也最常用的方式还是用WPS的发票打印功能吧,免费的
Deux
6
非常好用的在线工具,可以批量上传,并选择一张纸分几个区。
这是公司财务给我们教的方法。
1 个赞
有没有类似的免费软件?这种可以选份数批量打印的,比pdf合并工具方便多了,那些合并工具基本都没怎么考虑一个文件重复多次的情况
t35t
10
PDF-XChange(收费软件)
PDF-XChange Editor 这个免费版就支持打印全部的功能。
MinJun
11
这个章不重要啊,有些公司开出来的电子票都没有章呢,为什么一定要有章啊我不明白(来自一名财务的困惑)
财务不说,普通报销人员不懂啊,以为不带章这个发票就不起作用,所以就怕报销的时候不管用的
报销不一定要四张票,最简单是买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()