flyingsaucerproject / flyingsaucer Goto Github PK
View Code? Open in Web Editor NEWXML/XHTML and CSS 2.1 renderer in pure Java
License: Other
XML/XHTML and CSS 2.1 renderer in pure Java
License: Other
(reported by Ezhil [email protected])
Team - I want to make a PDF for my webpage using Flying Saucer to generate a PDF. With this below code I am able to generate a PDF but without any style and css.
I am trying to set my base URL using renderer.getSharedContext().setUserAgentCallback(new NaiveUserAgent(baseUrl))
but it is not working. it expects int type. Can anyone tell how to solve CSS and Images on the PDF ?
try {
// Define the URL
String urlcheck = "http://localhost:8888/index.html";
// Establish a URL connection
HttpURLConnection connection = (HttpURLConnection) new URL(urlcheck).openConnection();
connection.setRequestMethod("GET");
// Set up Basic Authentication with username "admin" and password "admin"
String username = "admin";
String password = "admin";
String authString = username + ":" + password;
String encodedAuthString = Base64.getEncoder().encodeToString(authString.getBytes());
connection.setRequestProperty("Authorization", "Basic " + encodedAuthString);
// Check the response code (200 indicates success)
int responseCode = connection.getResponseCode();
if (responseCode == 200) {
// Get the input stream from the connection
InputStream urlInputStream = connection.getInputStream();
LOG.info("PDF START ");
// Create an ITextRenderer instance
ITextRenderer renderer = new ITextRenderer();
// Convert the InputStream to a String
String htmlContent = convertInputStreamToString(urlInputStream);
HtmlCleaner cleaner = new HtmlCleaner();
TagNode rootTagNode = cleaner.clean(htmlContent);
// set up properties for the serializer (optional, see online docs)
CleanerProperties cleanerProperties = cleaner.getProperties();
// use the getAsString method on an XmlSerializer class
XmlSerializer xmlSerializer = new PrettyXmlSerializer(cleanerProperties);
String cleanedHtml = xmlSerializer.getAsString(rootTagNode);
LOG.info("cleanedHtml::"+cleanedHtml);
// Set the HTML content as the document
renderer.setDocumentFromString(cleanedHtml);
// Render to PDF
String baseUrl = "http://localhost:8888/";
renderer.getSharedContext().setUserAgentCallback(new NaiveUserAgent(baseUrl)); // Error
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
renderer.layout();
renderer.createPDF(outputStream);
renderer.finishPDF();
} else {
LOG.error("Failed to retrieve URL content. Response code: " + responseCode);
}
}
I am using a ThreadPoolExecutor to execute a pdf rendering task (flying-saucer-pdf:9.1.22 Java 11), here is the main code of each task:
ITextRenderer renderer = new ITextRenderer();
renderer.setDocumentFromString(html);
renderer.layout();
renderer.createPDF(outputStream);
It performs best when I set corePoolSize = 2
As I increase the corePoolSize, the time consuming of 'layout' and 'createPDF' method increases and the tps decreases.
Even if I increased the CPU from 2 cores to 8 cores, it didn't help.
so I wonder if there is any resource contention or lock between threads, and how can I improve the tps of single machine
... for example, using VeraPDF library.
See details in #280
to check #276 I tried to upgrade to 9.6.1 (from 9.1.22) causing my code to fail.
we are trying to generate pdf from a html that's generated in memory.
we then used to call renderer.setDocument(Document doc, String url)
that method seems to be private now.
all alternatives don't allow to pass a baseUrl parameter, causing relative URLs (CSS) to fail.
is there any other alternative?
Install JDK 21 and Gradle 8.5 (add to the PATH), then:
cd /tmp
git clone https://gitlab.com/DaveJarvis/KeenWrite keenwrite
cd keenwrite
gradle clean jar
The build succeeds. Then change 9.3.1 to 9.4.1, such as:
sed -i 's/flying-saucer-core:9.3.1/flying-saucer-core:9.4.1/' build.gradle
gradle clean jar
The build fails with:
> Task :compileJava FAILED
error: cannot access ParametersAreNonnullByDefault
class file for javax.annotation.ParametersAreNonnullByDefault not found
Note: Some input files use preview features of Java SE 21.
Note: Recompile with -Xlint:preview for details.
1 error
FAILURE: Build failed with an exception.
Hello, good day.
As mentioned in this conversation:
link
There is an error occurring when defining margins on the first page (@page:first) and the default page (@page). The issue is that some blank margins are being generated, as shown in the attached photos. In my case, the same problem occurs. I have the following configuration, and after the first page, these blank "margins" start to appear, breaking the visibility.
I have this configuration, maybe there is something wrong with my code?
@page :first{
margin-top: 5mm;
margin-left: 5mm;
margin-bottom: 5mm;
@bottom-right{
content: none;
}
@bottom-left{
content: none;
}
}
@page {
margin-top: 3.3cm;
margin-left: 1.5cm;
margin-right: 1.5cm;
margin-bottom: 1.7cm;
}
9.6.0 made most of setDocument methods private. I still need to use an option to provide Document object instead of String. This happened here (if I'm to believe release changelog): #281
In my case parsing html inside renderer causes an exception to be thrown. I use a more forgiving parser:
Document document = Jsoup.parse(htmlData);
document.outputSettings().syntax(Document.OutputSettings.Syntax.xml);
document.outputSettings().charset(StandardCharsets.UTF_8);
...
renderer.setDocument(new W3CDom().fromJsoup(document), "/");
In the method getFSFontMetrics of ITextTextRenderer (line 55), BaseFont.BBOXURY and BaseFont.BBOXLLY are used to calculate the ascent and descent of the font while this values are provided by iText.
I propose the following change :
result.setAscent(bf.getFontDescriptor(BaseFont.ASCENT, size));
result.setDescent(-bf.getFontDescriptor(BaseFont.DESCENT, size));
With this, the markers of list items are better vertically centered.
Hi, thanks for the great library, it's just been such a pleasure to work with!
I have a minor bug, relating to bold highlighting of markers.
Given the styling:
ol li::marker {
font-weight: bold;
}
I see bold being applied to the HTML generated document, but not to the PDF output.
HTML:
PDF:
Many thanks, Mark.
FlyingSaucer could be more tolerant to minor errors in html source.
Instead of throwing an exception, say, for non-closed html5 tags, it could close them automatically.
For example, we could use JSoup for job.
Triggered in discussion #277
Hi. Please add
public FormField[] getFormFields () {
Object[] objects = _componentCache.values ().toArray ();
FormField[] fields = new FormField[objects.length];
System.arraycopy (objects, 0, fields, 0, objects.length);
return fields;
}
to org.xhtmlrenderer.simple.extend.XhtmlForm.
I use this to get the form values without having to submit the entire form.
Cheers,
Jörn
Modernization of flyingsaucer and/or OpenPDF. Identify features needed for current tech era.
Find out which features other HTML to PDF Java libraries (such as openhtmltopdf) has which users need, and implement these features in flyingsaucer and/or OpenPDF.
in 9.7.x the default for xr.util-logging.loggingEnabled changed from false to true.
at least in the built versions @ mvnrepository.
I cannot see that change on github
any explanations for this?
Reported by (Ezhil](mailto:[email protected])
Team - I am trying to create a PDF using page url. But I am getting an error saying that
Can't load the XML resource (using TrAX transformer). org.xml.sax.SAXParseException; lineNumber: 6; columnNumber: 14; Open quote is expected for attribute "name" associated with an element type "meta".
It looks like renderer.setDocument(urlcheck)
check whether the URL has proper start and end HTML tag. Is there any we can skip this validation ?
try {
// Define the URL
String urlcheck = "https://en.wikipedia.org/wiki/IPhone_15";
// Establish a URL connection
HttpURLConnection connection = (HttpURLConnection) new URL(urlcheck).openConnection();
connection.setRequestMethod("GET");
// Check the response code (200 indicates success)
int responseCode = connection.getResponseCode();
if (responseCode == 200) {
// Get the input stream from the connection
InputStream urlInputStream = connection.getInputStream();
// Create an ITextRenderer instance
ITextRenderer renderer = new ITextRenderer();
// Set the HTML content as the document
renderer.setDocument(urlcheck);
// Render to PDF
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
renderer.layout();
renderer.createPDF(outputStream);
renderer.finishPDF();
}
If you create an xhtml file that has a content something like this:
<style> div.chapter { page-break-before: always; }for whatever-reason, a HTML/CSS I cannot fully control, applies float:left to a table-cell.
this results in the cell being rendered not as table-cell, but block.
this fails PDF generation with following error:
java.lang.ClassCastException: class org.xhtmlrenderer.render.AnonymousBlockBox cannot be cast to class org.xhtmlrenderer.newtable.TableCellBox (org.xhtmlrenderer.render.AnonymousBlockBox and org.xhtmlrenderer.newtable.TableCellBox are in unnamed module of loader 'app')
at org.xhtmlrenderer.newtable.TableSectionBox.recalcCells(TableSectionBox.java:83)
at org.xhtmlrenderer.newtable.TableBox.recalcSections(TableBox.java:204)
at org.xhtmlrenderer.newtable.TableBox.calcMinMaxWidth(TableBox.java:154)
at org.xhtmlrenderer.newtable.TableBox.layout(TableBox.java:221)
at org.xhtmlrenderer.layout.BlockBoxing.layoutBlockChild0(BlockBoxing.java:321)
at org.xhtmlrenderer.layout.BlockBoxing.layoutBlockChild(BlockBoxing.java:299)
at org.xhtmlrenderer.layout.BlockBoxing.layoutContent(BlockBoxing.java:90)
at org.xhtmlrenderer.render.BlockBox.layoutChildren(BlockBox.java:978)
at org.xhtmlrenderer.render.BlockBox.layout(BlockBox.java:858)
at org.xhtmlrenderer.render.BlockBox.layout(BlockBox.java:787)
at org.xhtmlrenderer.layout.BlockBoxing.layoutBlockChild0(BlockBoxing.java:321)
at org.xhtmlrenderer.layout.BlockBoxing.layoutBlockChild(BlockBoxing.java:299)
at org.xhtmlrenderer.layout.BlockBoxing.layoutContent(BlockBoxing.java:90)
at org.xhtmlrenderer.render.BlockBox.layoutChildren(BlockBox.java:978)
at org.xhtmlrenderer.render.BlockBox.layout(BlockBox.java:858)
at org.xhtmlrenderer.render.BlockBox.layout(BlockBox.java:787)
at org.xhtmlrenderer.pdf.ITextRenderer.layout(ITextRenderer.java:229)
see following test:
PdfTest.txt
I recommend removing these old packages and libraries. By removing flying-saucer-pdf-itext5 and flying-saucer-swt there will be a smaller, more maintainable code-base, which will ease the modernization of this library, eg. support modern HTML 5 etc. Also remove the jar files in lib/dev, these jar files should be included by Maven if they are needed.
https://github.com/flyingsaucerproject/flyingsaucer/tree/main/lib/dev
https://github.com/flyingsaucerproject/flyingsaucer/tree/main/lib
https://github.com/flyingsaucerproject/flyingsaucer/tree/main/flying-saucer-pdf-itext5 (iText 5 is EOL)
https://github.com/flyingsaucerproject/flyingsaucer/tree/main/flying-saucer-swt (SWT is not used much, could be removed or
forked out to a separate project under https://github.com/flyingsaucerproject)
https://github.com/flyingsaucerproject/flyingsaucer/tree/main/flying-saucer-swt-examples
I'm on version 9.4.1 ( last one before java 11) and i'm having trouble getting the letter-spacing CSS property to work, while other ones are working properly.
The only information I found is on notes/support.hml (which I assume is legacy info) and it doesn't specify yes or no.
Question: is the 'letter-spacing' working ? I found it in the code but, as said, has no effect when I use it.
I was using this project to complete the "Export html to pdf" function, and I found that when the src attribute in the img tag of html ends in a number (e.g. <img src= "http://localhost/img/01"), the exported pdf cannot render images normally, what should I do?
Hi,
Flying Saucer 9.7.2 is producing a very thick underline text decoration from an HTML with a "underline" element (<u></u>
) using Liberation Sans (it has a underline thickness of 150 — tested with 2.00.5 and 2.1.5 that I built myself).
I compared it to Open HTML to PDF 1.0.10 and found out that it hard codes the underline thickness to 50 in order to produce a more pleasant decoration.
Could you please confirm if the Flying Saucer behavior is expected and if so could you advise me on any workaround.
Best regards,
Sergio
Hello,
It seems that I'm not able to generate a PDF where the HTML content contains mixed western/CJK characters. I'm using a Unicode font (Arial Unicode MS), which contains all of the glyphs, but the resulting PDF does not display the CJK characters. I can't tell if it's dropping them or replacing them with something else.
I have a full example project here: https://github.com/emcintyre-hpe/flying-saucer-cjk. HOWEVER, because it uses a proprietary font, the repo is private. Please let me know which contributors here should have access and I will add them.
The example HTML looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta content="text/html"/>
<style type="text/css">
body {
font-family: "ArialUnicodeMS", sans-serif;
}
p.cjk {
font-family: "HeiseiKakuGo-W5-H";
}
</style>
<title>Simple Document</title>
</head>
<body>
<h1>Some Lorem Jeffsum</h1>
<p>Yeah, but John, if The Pirates of the Caribbean breaks down, the pirates don't eat the tourists. God creates
dinosaurs. God destroys dinosaurs. God creates Man. Man destroys God. Man creates Dinosaurs. I was part of something
special. Jaguar shark! So tell me - does it really exist?</p>
<p>Checkmate... This thing comes fully loaded. AM/FM radio, reclining bucket seats, and... power windows. Do you have
any idea how long it takes those cups to decompose. I was part of something special. Eventually, you do plan to have
dinosaurs on your dinosaur tour, right?</p>
<h2>Some Chinese text from Google Translate</h2>
<p>这东西满载而归。 AM/FM 收音机、斜躺桶形座椅和……电动车窗。 我们必须焚烧雨林、倾倒有毒废物、污染空气、破坏臭氧层!
因为也许如果我们把这个星球搞得够糟,他们就不再想要它了!</p>
<h2>Some Japanese text from Google Translate</h2>
<p>太った女性のことは忘れてください! あなたは太った女性に夢中です!English text interspersed with Japanese. 私たちをここから追い出してください!
もっと早く行かなければ...行け、行け、行け、行け、行け! 父がかつて私にこう言いました、笑えば世界もあなたと一緒に笑います、泣きなさい、そうすればこの野郎のことで泣けるようにしてあげますよ!
最終的には、恐竜ツアーに恐竜を参加させる予定ですよね?</p>
<h2>Some Korean text from Google Translate</h2>
<p>결국에는 공룡 투어에 공룡도 함께 할 계획이시죠? 운이 좋아서 얼음이 없어요. 이게 내 에스프레소 머신인가요? 뭐, 뭐야, 뭐야, 내 에스프레소 머신은 어떻게 샀어? 응, 하지만 존, 캐리비안의 해적이 망하면
해적들은 관광객을 잡아먹지 않아.</p>
<h2>The Japanese text below uses a dedicated Japanese font</h2>
<p class="cjk">太った女性のことは忘れてください! あなたは太った女性に夢中です! 私たちをここから追い出してください!
もっと早く行かなければ...行け、行け、行け、行け、行け! 父がかつて私にこう言いました、笑えば世界もあなたと一緒に笑います、泣きなさい、そうすればこの野郎のことで泣けるようにしてあげますよ!
最終的には、恐竜ツアーに恐竜を参加させる予定ですよね?</p>
</body>
</html>
The transformation code:
import static org.apache.commons.io.IOUtils.resourceToString;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import org.xhtmlrenderer.pdf.CJKFontResolver;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;
import org.xhtmlrenderer.simple.xhtml.XhtmlNamespaceHandler;
import com.lowagie.text.pdf.BaseFont;
/**
* Run with {@code mvn compile exec:java -Dexec.mainClass="CjkExample"}
*/
public class CjkExample {
public static void main(String[] args) throws IOException {
// Create renderer
ITextRenderer pdfRenderer = initRenderer();
// Create output stream
try (OutputStream pdf = Files.newOutputStream(Paths.get("target/example.pdf"))) {
// Read HTML file
String html = resourceToString("/example.html", StandardCharsets.UTF_8);
pdfRenderer.setDocumentFromString(html);
pdfRenderer.layout();
pdfRenderer.createPDF(pdf, true);
}
}
private static ITextRenderer initRenderer() throws IOException {
ITextFontResolver fonts = new CJKFontResolver();
ITextRenderer renderer = new ITextRenderer(fonts);
fonts.addFont("/fonts/ArialUnicodeMS.ttf", "ArialUnicodeMS", BaseFont.CP1252, true, null);
renderer.getSharedContext().setNamespaceHandler(new XhtmlNamespaceHandler());
return renderer;
}
}
And here is the resulting PDF
I'm trying to generate pdf from html. Depending on the content of the html I've encountered two strange cases.
Java code
public byte[] generatePdfWithEmptyPage() {
String html = getHtmlContent(2, 17);
return generatePdfWithContent(html);
}
public byte[] generatePdfWithCharactersSplit() {
String html = getHtmlContent(32, 19);
return generatePdfWithContent(html);
}
private byte[] generatePdfWithContent(String html) {
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
ITextRenderer renderer = new ITextRenderer(20f, 20);
renderer.setDocumentFromString(html);
renderer.layout();
renderer.createPDF(baos, false);
renderer.finishPDF();
return baos.toByteArray();
} catch (Exception e) {
System.out.println("Error during pdf generation");
throw new RuntimeException();
}
}
private String getHtmlContent(int fontSize, int fillerLineCount) {
String beginning = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n" +
"<html xmlns=\"http://www.w3.org/1999/xhtml\">\n" +
"<head><style></style></head><body>";
String dynamicLineSize = "<span style=\"font-size:" + fontSize + "pt;\">" + (fontSize + " ") + "<br/></span>\n";
String fillerLine = "<p style=\"line-height: 1; text-align: justify;\"><span style=\"font-family: times;\"> <span style=\"font-size: 10pt;\">E</span></span></p>";
String pdfContent = "<p style=\"line-height: 1; text-align: justify;\"><span style=\"font-family: times;\"><span style=\"font-size: 10pt;\">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</span></span></p>";
String ending = "</body></html>";
return beginning + dynamicLineSize + fillerLine.repeat(fillerLineCount) + pdfContent.repeat(2) + ending;
}
I have tried multiple ways to add Google fonts to the pdf but nothing worked for me.
Can you help me how to add the fonts style to pdf?
It seems to me that :last-child is not working ??
Update documentation. Making this issue so we remember.
See:
https://github.com/flyingsaucerproject/flyingsaucer/tree/gh-pages
https://flyingsaucerproject.github.io/flyingsaucer/r8/guide/users-guide-R8.html#pdf
(I might make a PR for this at some point in time.). @ivangal2
Arabic and hebrew texts not supporting
As mentioned in https://groups.google.com/g/flying-saucer-users/c/kw3FnbSIS2E, there is a package naming conflict between org.xmlrenderer:flying-saucer-pdf
and org.xmlrenderer:flying-saucer-core
: package org.xhtmlrenderer.simple
is present in both jars.
This causes projects using Java 9 modules to not be able to load both dependencies correctly. The fix proposed in the google groups thread would solve this.
There are several powerful features in newer CSS modules that would be great to take advantage of in this application, particularly colors with transparency/opacity. Has there been any effort or thoughts on supporting some more recent CSS modules?
FS should support HTML 5.
To update the flyingsaucerproject/flyingsaucer
library for essential HTML5 support, focus on key areas that are most impactful for modern web document standards: (chatgpt suggestions:)
HTML5 Parsing: Integrate an HTML5-compliant parser to accurately handle HTML5 documents. This is crucial for recognizing new semantic elements and properly parsing the document structure.
CSS3 Enhancements: Update the CSS rendering engine to support important CSS3 features such as flexbox for layout, media queries for responsive design, and transitions for visual effects. These are foundational for modern web design practices.
Semantic Elements Support: Specifically target support for new semantic elements like <article>
, <section>
, <nav>
, <header>
, <footer>
, and <figure>
. Ensuring these elements are correctly interpreted and rendered is essential for modern web documents.
Form Controls and Input Types: Enhance support for the new form elements and input types introduced in HTML5. This includes types like email
, date
, range
, and color
, which are increasingly used in web forms.
JavaScript Interface: Since HTML5 relies on JavaScript for dynamic content, consider how flyingsaucer
might either interface with JavaScript or provide hooks for external JavaScript interaction, especially for form validation and handling new input types.
Test Suite for HTML5: Develop a targeted test suite focusing on HTML5 features to ensure compatibility and adherence to standards. Utilize parts of the W3C HTML5 Test Suite for comprehensive coverage.
Documentation and Modular Approach: Update documentation to reflect the support for HTML5 and consider a modular approach for HTML5 features, allowing users to enable specific functionalities as needed. This strategy helps in managing performance implications and maintains backward compatibility.
By concentrating on these aspects, flyingsaucer
can significantly improve its HTML5 support, aligning it with current web standards and enhancing its utility for modern web document rendering.
Integrating an HTML5-compliant parser into the flyingsaucerproject/flyingsaucer
library involves several detailed steps to ensure accurate handling of HTML5 documents. These steps are crucial for recognizing new semantic elements and properly parsing the document structure:
Evaluate Existing Parser: Assess the capabilities and limitations of the current parsing mechanism in flyingsaucer
to understand how it handles HTML and where it falls short with HTML5 content.
Select an HTML5 Parser: Choose an HTML5-compliant parser that can be integrated into flyingsaucer
. Popular Java-based parsers like Jsoup or HTMLUnit have strong support for HTML5 and offer a good balance between performance and ease of use.
https://www.w3.org/TR/2011/WD-html5-20110405/
https://html.spec.whatwg.org/
Possibly some implementation details can be copied from:
https://github.com/openhtmltopdf/openhtmltopdf/
I have a problem adding an image to the entire size of a pdf page. I need to make a report in which the first page will be a special image, in a4 format and horizontal orientation (like the entire report).
And no matter what I did, what advice I tried from the Internet (stackoverflow, chatgpt), I was never able to do this simple operation.
I made a project on Github https://github.com/happydroid/pdf_full_page that generates a simplified report consisting of two pages - the first page with an image and the second page with some data. As you can see, trying to render the image in landscape orientation creates three whole pages:
As you can see, the page cannot be displayed completely, due to some indentation on the left and possibly on other sides, and I have turned off any indentation(paddings) in the styles for this page.
In the test project, I added the simplest example of rendering the project; I did not add all kinds of non-working methods.
Do you have any ideas on how this can be implemented using your library? Thank you.
<html>
<head>
<meta charset="UTF-8"/>
<style>
@page {
counter-increment: page;
size: A4 portrait;
margin-left: 64px;
margin-right: 64px;
}
div.content {
display: block;
font-family: Arial, sans-serif;
text-align: justify;
}
</style>
</head>
<body>
<div class="content">
<p>
<strong ><u>NOTICE OF ASSESSMENT ISSUED TO REGULATION OF THE SKILLS
DEVELOPMENT DEVELOPMENT DEVELOPMENT</u></strong>
</p>
</div>
</body>
</html>
Hi.
Please modifiy
private void updateSystemSelection() {
if (this.dotInfo != this.markInfo && panel != null) {
Clipboard clip = panel.getToolkit().getSystemSelection();
if (clip != null) {
String selectedText = lastHighlightedString;
try {
clip.setContents(new StringSelection(selectedText), null);
} catch (IllegalStateException ise) {
// clipboard was unavailable
// no need to provide error feedback to user since updating
// the system selection is not a user invoked action
}
}
}
}
in org.xhtmlrenderer.swing.SelectionHighlighter to
private void updateSystemSelection() {
if (this.dotInfo != this.markInfo && panel != null)
try {
Clipboard clip = panel.getToolkit().getSystemSelection();
if (clip != null) {
String selectedText = lastHighlightedString;
try {
clip.setContents(new StringSelection(selectedText), null);
} catch (IllegalStateException ise) {
// clipboard was unavailable
// no need to provide error feedback to user since updating
// the system selection is not a user invoked action
}
}
} catch (AccessControlException t) { }
}
so you won't get a SecurityException when running XHTMLRenderer in an unsigned applet.
Cheers,
Jörn
Hello,
I want to use flying saucer to get rid of some other PDF generating library and I am really happy to see that it supports margin boxes and running elements! The margin boxes seem to be working fine as long as I stick to content: "..."
but if I switch to running elements, like a div somewhere in the page with a class, which I give position: running(NAME)
and then apply to a margin box using content: element(NAME)
, it appears that the div is only rendered on the final page instead of on every page.
Is this a possible bug or does it sound like I am doing something wrong?
I can't generate pdf using externally loaded css stylesheet. It is generate without any styles.
Images with classpath prefix are not loaded too.
Everything works when I specify absolute path to file (with prefix file://), but this is not acceptable in my app.
My code:
final ITextRenderer renderer = new ITextRenderer();
renderer.setDocumentFromString(html);
renderer.getFontResolver().addFontDirectory(properties.fonts(), EMBEDDED);
renderer.layout();
final ByteArrayOutputStream pdf = new ByteArrayOutputStream();
renderer.createPDF(pdf);
write(properties.output(), pdf.toByteArray());
My HTML:
<html lang="pl-PL">
<head>
<title>Title</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="Content-Language" content="pl-PL"/>
<link href="classpath:templates/css/stylesheet.css" rel="stylesheet" type="text/css" media="print"/>
</head>
<body>...</body>
</html>
My maven dependecies:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>pdf-generator</artifactId>
<version>1.0.0-SNAPSHOT</version>
<name>pdf-generator</name>
<description>pdf-generator</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>flying-saucer-pdf-openpdf</artifactId>
<version>9.3.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
Our project is compiled using JDK8. Now,we have to upgrade flyingsaucer to recent version. But we found that the recent version could not compile on JDK8. 《The Flying Saucer User's Guide》mentioned that basic Java Runtime Environment is 1.4. So,how should we do can compile our project with flyingsaucer successful.
I had posted this issue initially on the code.google.com site, but it seems this one is not used anymore, so I'm trying it here...
Right now the latest code although having some great fixes compared to the code from dev.java.net, is unusable because of the following.
Could you have a look at it, please?
What steps will reproduce the problem?
What is the expected output?
Should resize normaly.
What do you see instead?
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at org.xhtmlrenderer.swing.ScalableXHTMLPanel.doRender(ScalableXHTMLPanel.java:173)
at org.xhtmlrenderer.swing.BasicPanel.paintComponent(BasicPanel.java:149)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JViewport.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JLayeredPane.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paintToOffscreen(Unknown Source)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(Unknown Source)
at javax.swing.RepaintManager$PaintManager.paint(Unknown Source)
at javax.swing.RepaintManager.paint(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at java.awt.GraphicsCallback$PaintCallback.run(Unknown Source)
at sun.awt.SunGraphicsCallback.runOneComponent(Unknown Source)
at sun.awt.SunGraphicsCallback.runComponents(Unknown Source)
at java.awt.Container.paint(Unknown Source)
at java.awt.Window.paint(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.seqPaintDirtyRegions(Unknown Source)
at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
What version of the product are you using? On what operating system?
Latest master from GitHub. Windows XP.
Please provide any additional information below.
It seems that when using setPrint(true) root.getMaster().getPaintingInfo()
always returns null.
After this exception, the application cannot recover, any subsequent call to repaint() triggers the Exception.
Any chance of including the support for PDF digital signature? If you think this makes sense I could contribute with a pull request
https://helpx.adobe.com/acrobat/using/signing-pdfs.html
I would prepare a pull request for this that would implement a
org.xhtmlrenderer.simple.PDFSigner
similar as
org.xhtmlrenderer.simple.PDFRenderer
That would encapsulate https://api.itextpdf.com/iText5/java/5.5.13.3/com/itextpdf/text/pdf/security/MakeSignature.html
Or would you suggest a better aproach?
how to fixed html table header?
thead style: display:table-header-group; not work
Flyingsaucer doesn't apply relative css files. For example:
index.html
<html>
<head>
<meta charset="utf-8">
<link href="invoice.css" media="print" rel="stylesheet">
<title>Invoice</title>
<meta name="description" content="Invoice demo sample">
</head>
<body>
<div>Hello Invoice</div>
</body>
</html>
invoice.css
div {
color:blue;
}
Main.java
try(var in = Files.newInputStream(Path.of("..."));
var out = Files.newOutputStream(Path.of("..."))) {
var doc = Jsoup.parse(in, "UTF-8","...");
var w3cDoc = new W3CDom().fromJsoup(doc);
ITextRenderer renderer = new ITextRenderer();
renderer.createPDF(w3cDoc, out);
}
What am I missing?
I have this error when I try to convert my html template to pdf.
Java Error:
java.lang.IllegalArgumentException: Font size too small: 0.0
at com.lowagie.text.pdf.PdfContentByte.setFontAndSize(PdfContentByte.java:1649)
at org.xhtmlrenderer.pdf.ITextOutputDevice.drawString(ITextOutputDevice.java:505)
at org.xhtmlrenderer.pdf.ITextTextRenderer.drawString(ITextTextRenderer.java:40)
at org.xhtmlrenderer.render.AbstractOutputDevice.drawText(AbstractOutputDevice.java:78)
at org.xhtmlrenderer.render.InlineText.paint(InlineText.java:129)
at org.xhtmlrenderer.render.InlineLayoutBox.paintInline(InlineLayoutBox.java:262)
at org.xhtmlrenderer.layout.Layer.paintInlineContent(Layer.java:258)
at org.xhtmlrenderer.layout.Layer.paint(Layer.java:315)
at org.xhtmlrenderer.pdf.ITextRenderer.paintPage(ITextRenderer.java:495)
at org.xhtmlrenderer.pdf.ITextRenderer.writePDF(ITextRenderer.java:443)
at org.xhtmlrenderer.pdf.ITextRenderer.createPDF(ITextRenderer.java:396)
at org.xhtmlrenderer.pdf.ITextRenderer.createPDF(ITextRenderer.java:328)
at fr.site.service.EmailService.convertHtmlToPdf(EmailService.java:417)
at fr.site.service.EmailService.GeneratePdfFromHtml(EmailService.java:406)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
I use Java 17 and Spring boot 3.1.0 and flying-saucer-pdf: 9.9.0
My Java Code:
public void convertHtmlToPdf(String html) throws IOException {
final String directoryPath = "src/main/resources/pdf/test.pdf";
OutputStream outputStream = new FileOutputStream(directoryPath);
ITextRenderer iTextRenderer = new ITextRenderer();
iTextRenderer.setDocumentFromString(html);
iTextRenderer.layout();
iTextRenderer.createPDF(outputStream);
outputStream.close();
}
My HTML file:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
<TITLE>Title</TITLE>
<STYLE type="text/css">
.outlook-group-fix {
width: 100% !important;
}
</STYLE>
<meta name="GENERATOR" content="MSHTML 11.00.10570.1001"/>
</head>
<body>
<div>
<!--[if mso | IE]>
<table role="presentation" style="WIDTH: 640px" cellSpacing="0" cellPadding="0" width=640 align="center" border="0">
<TBODY>
<TR>
<TD style="font-size: 0px; LINE-HEIGHT: 0px; mso-line-height-rule: exactly">
<![endif]-->
<div style="MAX-WIDTH: 100%; MARGIN: 0px auto">
<table role="presentation" style="font-size: 0px; WIDTH: 100%" cellspacing="0" cellpadding="0" align="center"
border="0">
<tbody>
<tr>
<td style="MAX-WIDTH: 640px; margin : auto; font-size: 0px; VERTICAL-ALIGN: top; PADDING-BOTTOM: 10px; DIRECTION: ltr; TEXT-ALIGN: center; PADDING-TOP: 5px; PADDING-LEFT: 8px; PADDING-RIGHT: 8px">
<!--[if mso | IE]>
<table role="presentation" cellSpacing="0" cellPadding="0" border="0">
<TBODY>
<TR>
<TD style="WIDTH: 640px; VERTICAL-ALIGN: top">
<![endif]-->
<div class="mj-column-per-100 outlook-group-fix"
style="font-size: 13px; WIDTH: 640px; MAX-WIDTH: 640px; VERTICAL-ALIGN: top; DIRECTION: ltr; TEXT-ALIGN: left; DISPLAY: inline-block">
<div align="center" style="margin:0cm;font-size:15px;font-family:'Calibri',sans-serif;">
</div>
<table role="presentation" cellspacing="0" cellpadding="0" width="100%" border="0">
<tbody></tbody>
</table>
<table style="border: none;width:640px;border-collapse:collapse;">
<tbody>
<tr>
<br/>
<td style="padding:0cm 0cm 0cm 0cm;text-align: justify; text-justify: inter-word;">
<p style="margin:0cm;font-size:15px;font-family:'Calibri',sans-serif;">
<span style="font-size:12px;font-family:'Arial',sans-serif;color:black;">Bonjour,</span>
<span style="font-size:12px;font-family: 'Arial',sans-serif;color:black;">
<br/>
<br/>Suite à votre réclamation
<span style="font-weight: bold;">Total Energies</span>
un dédommagement <span style="font-weight: bold;">22/04/2025</span> €. </span>
</p>
<br/>
<p style="margin:0cm;font-size:15px;font-family:'Calibri',sans-serif;">
<span style="font-size:12px;font-family: 'Arial',sans-serif;color:black;">
A partir de demain, nous vous invitons (<a
href="https://my.site.fr/space/con" target="_blank">https://my.site.fr/space/con</a>).
Vous pourrez y saisir sous 3 et 5 jours ouvrés, après avoir.
</span>
</p>
</td>
</tr>
<tr>
<td style="padding:0cm 0cm 0cm 0cm;text-align: justify; text-justify: inter-word;">
<br/>
<p style="margin:0cm;font-size:15px;font-family:'Calibri',sans-serif;">
<span style="font-size:12px;font-family: 'Arial',sans-serif;color:black;">
Nous notre site internet <a href="www.site.fr"
target="_blank">www.site.fr</a> ou au
<a href="tel:09" target="_blank">09</a> du de 8h à 17h.
</span>
</p>
<br/>
<p style="margin:0cm;font-size:15px;font-family:'Calibri',sans-serif;">
<span style="font-size:12px;font-family: 'Arial',sans-serif;color:black;">
La confiance.
</span>
</p>
<p style="margin:0cm;font-size:15px;font-family:'Calibri',sans-serif;">
<span style="font-size:12px;font-family: 'Arial',sans-serif;color:black;">
<br/>Bien cordialement,
<br/>Votre conseiller
</span>
</p>
<p style="margin:0cm;font-size:15px;font-family:'Calibri',sans-serif;">
<span style="font-size:12px;font-family: 'Arial',sans-serif;color:black;">
<br/> <br/>Retrouvez <a href="www.site.fr" target="_blank">www.site.fr</a>.
</span>
</p>
</td>
</tr>
</tbody>
</table>
</div>
<br/>
<!--[if mso | IE]>
</TD>
</TR>
</TBODY>
</table>
<![endif]-->
</td>
</tr>
</tbody>
</table>
</div>
<!--[if mso | IE]></TD></TR></TBODY></table><![endif]-->
</div>
</body>
</html>
Thanks for your support.
<div style="filter: blur(5px);"> This is test msg </div>
I have created PDF using above code. But it doesn't have blurry effect.
Any suggestions?
The documentation says that internal logging is disabled by default (logging doc)
But if the config file is not found (my case), the default value in the code is to enable internal logging (https://github.com/flyingsaucerproject/flyingsaucer/blob/main/flying-saucer-core/src/main/java/org/xhtmlrenderer/util/XRLog.java#L245C13-L245C36)
In some places, class names contain "iText" (e.g. ITextRenderer), although there seem to be no dependencies on iText. Is this a purely historical origin? Regarding licenses, this is a bit confusing.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.