我需要生成模板文档的自定义PDF副本.最简单的办法-我想-是创建具有这样的定制需要的情况发生,即一些占位符文本源PDF <first_name>和<last_name>,然后用正确的值替换这些.
我搜索过高和低,但实际上没有办法基本上采用源模板PDF,用实际值替换占位符并写入新的PDF?
我查看了PyPDF2和ReportLab,但似乎都无法做到.有什么建议?我的大多数搜索都使用了Perl应用程序CAM :: PDF,但我更喜欢将它全部保存在Python中.
没有直接的方法来做到可靠地工作.PDF与HTML不同:它们指定逐个字符的文本定位.它们甚至可能不包括用于呈现文本的整个字体,只包括呈现文档中特定文本所需的字符.我发现没有库会做更好的事情,比如在更新文本后重新包装段落.PDF大部分是仅显示格式,因此使用将标记转换为PDF而不是就地更新PDF的工具会更好.
如果这不是一个选项,你可以在像Acrobat这样的东西中创建一个PDF表格,然后使用像iText(AGPL)或pdfbox这样的PDF操作库,它有一个很好的clojure包装器,叫做pdfboxing,可以处理其中的一些.
根据我的经验,Python对PDF编写的支持非常有限.到目前为止,Java是最好的语言支持.此外,您得到了您所支付的费用,因此如果您将其用于商业用途,则可能需要支付iText许可证.我已经有很好的结果编写python包装器围绕PDF操作CLI工具,如pdfboxing和ghostscript.对于你的用例而言,这可能比试图将其软件化为Python的PDF生态系统要容易得多.
小智 7
没有明确的解决方案,但我发现了 2 个大多数情况下都有效的解决方案。
在 python https://github.com/JoshData/pdf-redactor 中给出了很好的结果。这是示例代码:
# Redact things that look like social security numbers, replacing the
# text with X's.
options.content_filters = [
# First convert all dash-like characters to dashes.
(
re.compile(u"Tom Xavier"),
lambda m : "XXXXXXX"
),
# Then do an actual SSL regex.
# See https://github.com/opendata/SSN-Redaction for why this regex is complicated.
(
re.compile(r"(?<!\d)(?!666|000|9\d{2})([OoIli0-9]{3})([\s-]?)(?!00)([OoIli0-9]{2})\2(?!0{4})([OoIli0-9]{4})(?!\d)"),
lambda m : "XXX-XX-XXXX"
),
]
# Perform the redaction using PDF on standard input and writing to standard output.
pdf_redactor.redactor(options)
Run Code Online (Sandbox Code Playgroud)
完整示例可以在这里找到
在 ruby 中https://github.com/gettalong/hexapdf适用于黑色文本。示例代码:
require 'hexapdf'
class ShowTextProcessor < HexaPDF::Content::Processor
def initialize(page, to_hide_arr)
super()
@canvas = page.canvas(type: :overlay)
@to_hide_arr = to_hide_arr
end
def show_text(str)
boxes = decode_text_with_positioning(str)
return if boxes.string.empty?
if @to_hide_arr.include? boxes.string
@canvas.stroke_color(0, 0 , 0)
boxes.each do |box|
x, y = *box.lower_left
tx, ty = *box.upper_right
@canvas.rectangle(x, y, tx - x, ty - y).fill
end
end
end
alias :show_text_with_positioning :show_text
end
file_name = ARGV[0]
strings_to_black = ARGV[1].split("|")
doc = HexaPDF::Document.open(file_name)
puts "Blacken strings [#{strings_to_black}], inside [#{file_name}]."
doc.pages.each.with_index do |page, index|
processor = ShowTextProcessor.new(page, strings_to_black)
page.process_contents(processor)
end
new_file_name = "#{file_name.split('.').first}_updated.pdf"
doc.write(new_file_name, optimize: true)
puts "Writing updated file [#{new_file_name}]."
Run Code Online (Sandbox Code Playgroud)
在这里,您可以将选定文本上的文本涂黑。