如何利用tempfile在PDF中插入动态生成的条形码?
解决方案
你的核心需求是避免磁盘IO瓶颈,最优方案是直接将Treepoem生成的图像转为字节流,通过PyMuPDF的stream参数插入,全程在内存中操作,完全不需要临时文件。之前的tempfile用法存在两个关键错误:
之前尝试的问题分析
第一种尝试的错误
tempfile.TemporaryFile()在Windows系统下默认以独占模式打开,PyMuPDF无法再次打开这个文件,导致权限错误。barcode_tempfile.write(b'{barcode_contents}')是完全错误的写法:这只是把字符串{barcode_contents}转成二进制写入,并没有真正写入图像数据,你需要先将PIL图像对象转为字节流。
第二种尝试的错误
tempfile.TemporaryFile('barcode_tempfile')参数使用错误:TemporaryFile的第一个参数是文件模式(比如'wb'),不是文件名,因此触发参数错误。
正确实现方式(无磁盘IO,推荐)
直接使用io.BytesIO将PIL图像转为字节流,然后通过PyMuPDF的stream参数传入,全程在内存中操作:
import fitz import io import treepoem # 生成条形码并转为单色图像 barcode_img = treepoem.generate_barcode( barcode_type='datamatrixrectangular', data='10000010' ).convert('1') # 将图像转为字节流 img_byte_arr = io.BytesIO() barcode_img.save(img_byte_arr, format='JPEG') img_byte_arr.seek(0) # 将文件指针移到开头,供PyMuPDF读取 # 操作PDF pdf_file = fitz.open() pdf_file.new_page() page = pdf_file[0] rect = fitz.Rect(70, 155, 200, 230) # 使用stream参数传入字节流,无需磁盘文件 page.insert_image(rect, stream=img_byte_arr) pdf_file.save('example_pdf_with_barcode.pdf')
若必须使用临时文件的替代方案
如果你一定要用临时文件,需要使用tempfile.NamedTemporaryFile,并设置delete=False(让文件在关闭后不立即删除,供PyMuPDF读取),用完后手动删除:
import fitz import tempfile import treepoem import os # 生成条形码并转为单色图像 barcode_img = treepoem.generate_barcode( barcode_type='datamatrixrectangular', data='10000010' ).convert('1') # 创建命名临时文件,设置delete=False with tempfile.NamedTemporaryFile(suffix='.jpg', delete=False) as temp_file: barcode_img.save(temp_file, format='JPEG') temp_file_path = temp_file.name # 操作PDF pdf_file = fitz.open() pdf_file.new_page() page = pdf_file[0] rect = fitz.Rect(70, 155, 200, 230) page.insert_image(rect, filename=temp_file_path) pdf_file.save('example_pdf_with_barcode.pdf') # 手动删除临时文件 os.unlink(temp_file_path)
关键说明
- 优先选择字节流方案:完全避免磁盘读写,性能更优,适合大规模批量处理场景。
seek(0)的作用:将字节流的文件指针移到起始位置,否则PyMuPDF会从当前指针位置(文件末尾)开始读取,导致读取到空数据。
内容的提问来源于stack exchange,提问作者Jamjar91
相关产品推荐
相关产品推荐

