首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PYFPDF:用多个单元调整单元高度

PYFPDF:用多个单元调整单元高度
EN

Stack Overflow用户
提问于 2022-03-15 03:02:58
回答 1查看 225关注 0票数 0

我有一个问题,调整细胞的高度取决于多个单元格的高度,这个多单元格改变它的高度由字数和width.My代码,我正在测试如下。

代码语言:javascript
复制
datos = ["hola","Esto es el texto que determina el tamaño"]
pdf = FPDF()
pdf.add_page()
pdf.set_font('Arial', 'B', 8)
line_height = pdf.font_size * 2.5
t = 0
lh_list = [] #list with proper line_height for each row #flag
a = []


#create lh_list of line_heights which size is equal to num rows of data
for row in datos:
    x = row.split()
    f = len(x)
    a.append(f)
    if f>1:
        alto = line_height
        lh_list.append(alto)
    else:
        lh_list.append(line_height)
print(lh_list)
print(a)
for j,row in enumerate(datos):
    if a[j]>1:
        pdf.multi_cell(40,lh_list[j],row,1,'J')
    else:
        pdf.cell(40,lh_list[j]*2,row,1,0,'J')

pdf.output('table_with_cells.pdf')

结果是:结果

所期望的结果是:预期结果

EN

回答 1

Stack Overflow用户

发布于 2022-11-08 14:04:56

使用split_only参数multi_cell来计算文本的每个单元格所需的行数。有了这些信息,您就可以正确地计算每个单元格的确切位置。请注意,必须将max_line_height参数理解为单元格的每一行的行高。这意味着,如果内容需要在单元格内打印1-3行,则值为3、6或9毫米的单元格将产生一个单元格。

代码语言:javascript
复制
from fpdf import FPDF


def pt2mm(points: int) -> float:
    """calculates size from points (eg. font size) to mm

    Parameters
    ----------
    pt : int
        size in points

    Returns
    -------
    float
        size in mm
    """
    return 0.3528 * points

pdf = FPDF()
pdf.add_page()
default_font_size = 8
pdf.set_font('helvetica', 'B', default_font_size)
line_height = default_font_size * 1.1
line_oversize = line_height - default_font_size
print(f'{default_font_size} -> {line_height} -> {line_oversize}')
table_data = [
    ("hola", "Esto es el texto que determina el tamaño"),
    ("hola hola hola hola hola", "Esto es el texto que determina el tamaño"),
    ("hola hola hola hola hola ", "Esto es el texto"),
    ("hola hola ", "Esto es el texto"),
]
col_widths = (30, 50)
col_align = ('L', 'L')

x_val_first_col = pdf.get_x()  # we have to draw the cell border by ourself, need start point coordination
for row in table_data:
    # check if any cell in this row has line breaks, saves maximum lines and calculate height and somem positions
    max_n = 1
    for col_width, row_data in zip(col_widths, row):
        max_n = max(max_n, len(pdf.multi_cell(w=col_width, txt=row_data, split_only=True)))
    row_height = (max_n + line_oversize) * pt2mm(default_font_size)
    row_y_top = pdf.get_y() + line_oversize / 2 * pt2mm(default_font_size)
    row_y_bottom = pdf.get_y() + row_height
    # draw each cell by itself
    for col_width, cell_data, cell_align in zip(col_widths, row, col_align):
        n_cell = len(pdf.multi_cell(w=col_width, txt=cell_data, split_only=True))
        if n_cell < max_n:
            y_cell_shift = (max_n - n_cell) * pt2mm(default_font_size) / 2
        else:
            y_cell_shift = 0
        cell_y_top = row_y_top + y_cell_shift
        pdf.set_xy(pdf.get_x(), cell_y_top)
        pdf.multi_cell(w=col_width, txt=cell_data, border=0, align=cell_align, new_x='RIGHT')
    # draw the horizontal line and return curser
    pdf.line(x1=x_val_first_col, y1=row_y_bottom, x2=x_val_first_col+sum(col_widths), y2=row_y_bottom)
    pdf.set_xy(x=x_val_first_col, y=row_y_bottom)
pdf.output('example.pdf')

单元格的边界需要分开绘制。在我的例子中,我只画水平线。要理解为什么要这样做,只需在我的示例中将border=0更改为border=1即可。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71476543

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档