我正在使用 Python 中的 ReportLab 生成 PDF 文件。我的项目结构如下所示:
project_root/
│
├── workspace/
│ └── generated_report.pdf
│
└── data/
├── folder_1/
│ └── file_1.txt
└── folder_2/
└── file_2.txt
我在工作流程文件夹中生成 PDF,数据文件夹包含我想要在 PDF 中链接到的嵌套目录和文件。
这是我的代码
import os
from reportlab.platypus import Paragraph
def generate_link(pdf_path, file_path, styles):
link = f'file://{os.path.join(os.path.dirname(os.path.abspath(pdf_path)), os.pardir, os.path.relpath(file_path))}'
return Paragraph(f'<a href="{link}">{os.path.relpath(file_path)}</a>', styles['BodyText'
])
此代码在 PDF 中生成绝对链接,但我想让它们相对,这样如果我将工作流程和数据文件夹移动到另一个位置,链接仍然有效。
使用
<a href="STRING_A">STRING_B</a>
时,STRING_A
是将用于链接/重定向的值,而 STRING_B
是代替链接显示的(强制)值。
要生成相对链接,您可能需要更改
STRING_A
的值并应用 os.path.relpath
,就像在 STRING_B
上所做的那样。请注意,os.path.relpath
可以采用第二个参数 [0],称为 start
。如果您不从“工作流程”/项目的根目录执行脚本,则必须将 start
设置为此路径。
import os
from reportlab.platypus import Paragraph
# Added a `project_root` parameter, it is the path of your project/workflow root.
# If `project_root` is the same as `pdf_path`, just remove the param and replace
# `project_root` by `pdf_path` in the rest of the function.
# \/\/\/\/\/\/
def generate_link(pdf_path, file_path, styles, project_root):
# The way you compute this path seems a little bit convoluted
# but if it works, you may keep it as-is.
computed_pdf_path = os.path.join(os.path.dirname(os.path.abspath(pdf_path)), os.pardir, os.path.relpath(file_path))
relative_path = os.path.relpath(computed_pdf_path, os.path.dirname(project_root))
link = f'file://{relative_path}'
return Paragraph(f'<a href="{link}">{relative_path}</a>', styles['BodyText'])
[0] https://docs.python.org/3/library/os.path.html#os.path.relpath