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

PyMuPDF与ReportLab实现交互式PDF表单时文本框对齐异常求助

交互式PDF表单文本框对齐问题排查

我正在开发一款程序,接收表单文件后通过标记定位并绘制表单元素,将其转换为交互式PDF表单。目前单选按钮能在页面上正确对齐,但文本框始终无法正常对齐。

我推测问题可能出在前置文本长度的计算方式上,或是不同工具包之间的计量单位存在差异,但始终无法确定原因。

以下是获取表单元素位置和尺寸、将其写入空白PDF并与原表单合并的代码:

def extract_pdf(filename):
    script_dir = os.path.dirname(os.path.abspath(__file__))
    file_path = os.path.join(script_dir, filename)
    print(file_path)
    document = fitz.open(file_path)
    markers = []
    font = fitz.Font()
    print(document)


    for page_num in range(len(document)):
        page = document.load_page(page_num)
        text = page.get_text('dict')  
        for block in text['blocks']:
            for line in block['lines']:
                for span in line['spans']:
                    if '[' in span['text']:
                        bracket_matches = re.finditer(r'\[([^\]]*)\]', span['text'])
                        for match in bracket_matches:
                            start_index = match.start()
                            end_index = match.end()

                            preceding_text = span['text'][:start_index]
                            bracket_text = span['text'][start_index:end_index]
                                
                                
                            preceding_text_width = font.text_length(preceding_text, span['size'])
                            bracket_text_width = font.text_length(bracket_text, span['size'])                               

                            start_x = span['bbox'][0] + preceding_text_width
                            width = bracket_text_width
                            height = span['bbox'][3] - span['bbox'][1]
                            print(height)
                            markers.append({
                                "type": "text",
                                "x": start_x,
                                "y": span['bbox'][3],
                                "width": width,
                                'height': height,
                                "page_num": page_num
                                })               

    original_pdf = PdfReader(open(filename, 'rb'))
    output_pdf = PdfWriter()
    
    for i in range(len(original_pdf.pages)):
        original_page = original_pdf.pages[i]
        original_page_width = original_page.mediabox[2]
        original_page_height = original_page.mediabox[3]
        
        packet = io.BytesIO()
        can = canvas.Canvas(packet, pagesize=(original_page_width, original_page_height))
        acroform = can.acroForm
    
        text_counter = 1
        for marker in markers:
            text_counter += 1
            if marker["type"] == "text":
                acroform.textfield(
                    name=f"TextField{text_counter}",
                    x=marker['x'],
                    y=original_page_height - marker['y'],
                    width=marker['width'],
                    height=marker['height'],
                    borderStyle="solid",
                    borderWidth=1,
                    forceBorder=True,
                    maxlen=50            
                )
            
        can.save()

        packet.seek(0)
        new_pdf = PdfReader(packet)
        page = original_pdf.pages[i]
        if new_pdf.pages[0]:
            page.merge_page(new_pdf.pages[0])
        
        output_pdf.add_page(page)
        
    save_path  = os.path.dirname(os.path.abspath(__file__))
    save_file = os.path.join(script_dir, 'output.pdf')
    with open(save_file, 'wb') as f:
        output_pdf.write(f)

如图所示,单选按钮大致与标记居中对齐,但文本框位置混乱,表单页眉处的文本框在X轴上偏右过多。我猜测是text_length方法未正确转换前置文本宽度,可能是空格计算有误?打印前置文本和文本长度时一切看似正常,恳请提供技术指导。

原表单样式:
原表单样式

最终表单样式:
最终表单样式

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 12:25:56