There is no direct way to do this that will work reliably. PDFs are not like HTML: they specify the positioning of text character-by-character. They may not even include the whole font used to render the text, just the characters needed to render the specific text in the document. No library I've found will do nice things like re-wrap paragraphs after updating the text. PDFs are for the most part a display-only format, so you'll be much better off using a tool that turns markup into a PDF than updating the PDF in-place.
If that's not an option, you can create a PDF form in something like Acrobat, then use a PDF manipulation library like iText (AGPL) or pdfbox, which has a nice clojure wrapper called pdfboxing that can handle some of that.
From my experience, Python's support for writing to PDFs is pretty limited. Java has, by far, the best language support. Also, you get what you pay for, so it would probably be worth paying for a iText license if you're using this for commercial purposes. I've had pretty good results writing python wrappers around PDF-manipulation CLI tools like pdfboxing and ghostscript. That will probably be much easier for your use case than trying to shoehorn this into Python's PDF ecosystem.
Answer from Lucas Wiman on Stack OverflowThere is no direct way to do this that will work reliably. PDFs are not like HTML: they specify the positioning of text character-by-character. They may not even include the whole font used to render the text, just the characters needed to render the specific text in the document. No library I've found will do nice things like re-wrap paragraphs after updating the text. PDFs are for the most part a display-only format, so you'll be much better off using a tool that turns markup into a PDF than updating the PDF in-place.
If that's not an option, you can create a PDF form in something like Acrobat, then use a PDF manipulation library like iText (AGPL) or pdfbox, which has a nice clojure wrapper called pdfboxing that can handle some of that.
From my experience, Python's support for writing to PDFs is pretty limited. Java has, by far, the best language support. Also, you get what you pay for, so it would probably be worth paying for a iText license if you're using this for commercial purposes. I've had pretty good results writing python wrappers around PDF-manipulation CLI tools like pdfboxing and ghostscript. That will probably be much easier for your use case than trying to shoehorn this into Python's PDF ecosystem.
There is no definite solution but I found 2 solutions that works most of the time.
In python https://github.com/JoshData/pdf-redactor gives good results. Here is the example code:
# 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)
Full Example can be found here
In ruby https://github.com/gettalong/hexapdf works for black out text. Example code:
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}]."
In this you can black out text on select text will be visible.
How do I generate a PDF report from HTML in Python?
Use WeasyPrint for print-oriented HTML and CSS, or Playwright with Chromium when the report needs JavaScript. Nutrient API provides hosted HTML-to-PDF conversion with custom fonts, headers, footers, and page numbers.
Can I generate PDFs with embedded images using Python?
Yes. ReportLab and WeasyPrint can include images in generated documents. Use img2pdf when each source image should become a PDF page.
How do I generate a PDF report with tables and charts in Python?
ReportLab supports tables and flowables through Platypus, with charts in its reportlab.graphics module. For chart-heavy reports, combine matplotlib (for chart images) with ReportLab or Nutrient API to embed them in PDF output.
Hi!
I'm kinda losing my mind. This might be misplaced but it feels like I'm the only one with this problem.
I have to generate a PDF from some sort of template with user data. Our initial solution that made sense was Word form letters. The user, or our staff, can create a word document, get a CSV from a Django Rest Framework serializer, use that as a field source for the form letter, put those in and we fill that in with a python library and generate a pdf with libre office headless.
But now the requirements changed (or were different but product management didn't think that was an issue so it wasn't clearly communicated) and we need to have more logic in there than the form letters allow us to do. Like, "if this field is False just throw out those other fields". Basic Jinja conditionals.
But I literally can't find anything like this. There is ReportLab but they have "contact sales" prices for the version with some sort of template file we could use. And the project is not really warranting "contact sales" prices.
There's of course Latex but I'm the only person in the company that has any experience with Latex and the document should preferably look like a letter from our users so we need to implement some design elements that require a lot of fiddling with Latex and I'd have to do it but paying for an engineer to do the job of an intern is not a good idea.
All I find is basically printing HTML generated from a Jinja template but I just don't find anything that supports headers and footers. We need stuff like page numbers and disclaimers in the footer, company logo in the header and it looks like Latex is the only option.
Even Pandoc seems to require you to put some Latex in the metadata it will use to generate a header.
Am I just missing an obvious solution or is this really a very unsolved problem?
I have an application for which I need to auto-generate some diagrams as PDF files. The graphics aren't anything particularly fancy, just line drawings and some text.
My first instinct was to generate LaTeX code in Python to draw the graphics with TikZ, but I feel like there's probably a better way without the middleman. I see there are a variety of different libraries for generating PDFs, so I'm looking for someone who has used one or more of them to maybe point me towards one which would suit my needs the best.
Edit: I should mention that I currently am manually creating the diagrams in LaTeX with TikZ. It works "well" (speaking as someone fluent in LaTeX, I doubt anyone who isn't would think this is a good solution at all), but it feels weird to add an extra step of generating code that generates the files instead of generating the files I need directly. But TikZ is a good example of the type of control I need - these diagrams aren't super fancy, just showing and labeling arrangements of chairs in rooms.
I'm having a nightmare with software for generating invoice documents for a platform I'm developing.
The problem being I have multiple tenants and need to make the templates reasonably easy to edit/create.
Currently I'm doing this via pug > html > puppeteer, however puppeteer doesn't seem stable or reliable enough for my needs, and document generation times are in the 10s of seconds.
I've been playing with PDFMake and jsPDF, however both of these make it very difficult to design templates in a reasonable format.
I've also toyed with JSReports, Gotenburg and Wkhtmltopdf and found all of them pretty awful.
If I was working on Windows I'd use Crystal Reports, as the document generation is extremely flexible and easy to edit, however the platform is running in docker.
Is there some silver bullet out there to crack this problem that isn't $100-500 a month?
edit - Couldn't find a reasonable solution so I built one!