I am converting a html document to a pdf document and send it with java mail.
I want to insert an image on the top of the pdf document with:
<img alt="Logo" class="logo" src="https://www.somesite.org/images/logo.png"/>
But it isnt shown in the pdf document.
The link is working correctly, i tried it in my browser.
When i put in a absolute path to the image on my server he finds the path, but the email programm doesnt have access to our server of course, except of the link i want to use...
Isnt it possible to use such links?
EDIT:
final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setValidating(false);
DocumentBuilder builder = documentBuilderFactory.newDocumentBuilder();
builder.setEntityResolver(FSEntityResolver.instance());
SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy");
String filename = wrapper.GetHtmlFilename(this.getClass().getName());
String html = wrapper.GetHtmlFile(filename, "UTF-8");
String result = wrapper.GetBody(html);
document = builder.parse(new ByteArrayInputStream(result.getBytes("UTF-8")), "UTF-8");
baos = new ByteArrayOutputStream();
renderer = new ITextRenderer();
renderer.setDocument(document, null);
renderer.layout();
renderer.createPDF(baos);
Related
I create a file pdf from html template using Spring Boot, flying saucer, thymeleaf. But image is not displaying in my file.
Project structure:
code html:
<div class="col-xs-6 invoice-col-2">
<img src="../static/images/mastercard.png" alt="mastercard"></img>
</div>
When I change img tag to:
<img src="../static/images/mastercard.png" alt="mastercard" th:src="#{static/images/mastercard.png}"></img>
When I create PDF file, I get an error:
org.thymeleaf.exceptions.TemplateProcessingException: Link base "static/images/mastercard.png" cannot be context relative (/) or page relative unless you implement the org.thymeleaf.context.IWebContext interface (context is of class: org.thymeleaf.context.Context)
Try using Spring's classpath: prefix. This loads your file directly from the classpath, no matter if you are running from a .jar or within your IDE. Here is an example:
<img alt="mastercard" th:src="#{classpath:static/images/mastercard.png}" />
More information about classpath: can be found in the official documentation.
In order to embed an image in a PDF generated by Flying Saucer,
1) Convert the image to a base64 encoded string.
Path path = Paths.get("src/main/resources/static/images/mastercard.png");
String base64Image = convertToBase64(path);
Function to convert image stored in a path like shown above, to a base64 encoded string
private String convertToBase64(Path path) {
byte[] imageAsBytes = new byte[0];
try {
Resource resource = new UrlResource(path.toUri());
InputStream inputStream = resource.getInputStream();
imageAsBytes = IOUtils.toByteArray(inputStream);
} catch (IOException e) {
System.out.println("\n File read Exception");
}
return Base64.getEncoder().encodeToString(imageAsBytes);
}
2) Set the base64 encoded image in the thymeleaf context
Context context = new Context();
String image = "data:image/png;base64, " + base64Image;
context.setVariable("image", image);
String html = templateEngine.process("template", context);
3) In HTML, set the value of image as shown below:
<img th:src="${image}" style="width: 200px; height=100px"/>
4) Finally, render the HTML template to PDF
ITextRenderer renderer = new ITextRenderer();
renderer.setDocumentFromString(html); // html -> String created in Step 2
renderer.layout();
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
renderer.createPDF(baos)
Now you have the byteArrayOutputStream of the generated PDF, with which you can choose to store them to a file server or serve it to a client in a format of your choice.
Use standard html src atribute and relative path from root of the project.
You can put your image in the root of the project and use it like this:
<img src="mastercard.png" />
If you want to resource folders you can set it like this:
<img src="src/main/resources/static/images/mastercard.png" />
I faced the same issue but reading image file from disk is little costly, I would suggest you go with uri-data
http://www.tothenew.com/blog/using-data-urls-for-embedding-images-in-flying-saucer-generated-pdfs/
Because you anyway going to read image to generate PDF, better keep it in template.
I am trying to attach the HTML file to the Gmail body, but the image which I have attached in the HTML file is not getting displayed in Gmail (working fine in Outlook).I have tried putting the base64 code of image but still the same issue (In this case even in Outlook the image is blocked). I even tried with "Content ID generator".
Please see following code what I have tried), but unable to display image.
Can some one tell me how to solve this issue?
(Note: I have used the free marker template to generate the HTML code)
Map<String, String> inlineImages = new HashMap<String, String>();
inlineImages.put("image2", "C:\\Users\\xxxxxxx\\Desktop\\Capture1.jpg");
model.put("image", inlineImages);
String text = geFreeMarkerTemplateContent(model);
System.out.println("Template content : "+text);
helper.setText(text, true);
MimeBodyPart bodyPart = new MimeBodyPart();
bodyPart.setContent(text, "text/html");
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(bodyPart);
MimeBodyPart imagePart = new MimeBodyPart();
imagePart.setHeader("Content-ID", "image2");
imagePart.setDisposition(MimeBodyPart.INLINE);
// attach the image file
imagePart.attachFile("C:\\Users\\xxxxx\\Desktop\\Capture1.jpg");
multipart.addBodyPart(imagePart);
mimeMessage.setContent(multipart);
I have a XML in my webserver, when i try to open it in a browser it displays properly as raw xml, but the same when tried to display it in an iframe with its url, it displays as string and not as raw xml.
<iframe type="application/xml" src="http://www.w3schools.com/xml/simple.xml"></iframe>
http://jsfiddle.net/qvRzT/8/
Please note that I cannot load xml as a content in iframe because the xml is dynamically generated, I can only use its url to load in iframe.
In my scenario, the XML source from API response will be passed to HTML iframe tag source. Response content type text/plain will display plain XML content in html page without parsing
HTML
<iframe type="text/plain" data-bind="attr: {src: ('api/document/view?token=' + doc.downloadUrl)}"></iframe>
C# API response
public HttpResponseMessage View(string token)
{
HttpResponseMessage result = null;
var localFilePath ="D:\sample.xml";
var fileInfo = new System.IO.FileInfo(localFilePath);
result = Request.CreateResponse(HttpStatusCode.OK);
result.Content = new StreamContent(new FileStream(localFilePath, FileMode.Open, FileAccess.Read));
string FileMimeType = MimeMapping.GetMimeMapping(fileInfo.Name);
if (FileMimeType == "text/xml")
{
result.Content.Headers.ContentType = new
System.Net.Http.Headers.MediaTypeHeaderValue("text/plain");
}
else
result.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(FileMimeType);
result.Content.Headers.ContentDisposition = new
System.Net.Http.Headers.ContentDispositionHeaderValue("inline");
result.Content.Headers.ContentDisposition.FileName = fileInfo.Name;
return result;
}
This is because the browser sees the XML as the source of the page. So it will be marked up as an XML file. When the browser gets the iframe and loads the XML, it handles the source as HTML. (Even if no HTML tag is provided.)
The code below is generating the HTML report fine on a new browser window, but it is writing the HTML file on the app server. Is there a way to generate an HTML report in Jasper without having to write the HTML file to the app server?
I can do it in PDF using JasperRunManager.runReportToPdfStream(), but there's no such method for HTML. Any ideas?
//For HTML file
String reportPath = JasperRunManager.runReportToHtmlFile(sourceFileName, parameters, conn);
File reportHtmlFile = new File(reportPath);
FileInputStream fis = new FileInputStream(reportHtmlFile);
byte[] bytes = new byte[(int)reportHtmlFile.length()];
fis.read(bytes);
response.setHeader("Content-Disposition","inline; ");
response.setContentType("text/html");
response.setContentLength(bytes.length);
servletOutputStream.write(bytes, 0, bytes.length);
servletOutputStream.flush();
servletOutputStream.close();
I have a process where the html is stored in database with image links. the images are also stored in db as well. I've created a controller action which reads the image from database. the path I'm generating is something like /File/Image?path=Root/test.jpg.
this image path is embedded in html in img tag like <img alt="logo" src="/File/Image?path=Root/001.jpg" />
I'm trying to use itextsharp to read the html from the database and create a pdf document
string _html = GenerateDocumentHelpers.CommissioningSheet(fleetId);
string _html = GenerateDocumentHelpers.CommissioningSheet(fleetId);
Document _document = new Document(PageSize.A4, 80, 50, 30, 65);
MemoryStream _memStream = new MemoryStream();
PdfWriter _writer = PdfWriter.GetInstance(_document, _memStream);
StringReader _reader = new StringReader(_html);
HTMLWorker _worker = new HTMLWorker(_document);
_document.Open();
_worker.Parse(_reader);
_document.Close();
Response.Clear();
Response.AddHeader("content-disposition", "attachment; filename=Commissioning.pdf");
Response.ContentType = "application/pdf";
Response.Buffer = true;
Response.OutputStream.Write(_memStream.GetBuffer(), 0, _memStream.GetBuffer().Length);
Response.OutputStream.Flush();
Response.End();
return new FileStreamResult(Response.OutputStream, "application/pdf");
This code gives me an illegal character error. this comes from the image tag, it is not recognizing ? and = characters, is there a way I can render this html with img tag so that when I create a pdf it renders the html and image from the database and creates a pdf or if itextsharp can't do it, can you provide me with any other third party open source tools that can accomplish this task?
If the image source isn't a fully qualified URL including protocol then iTextSharp assumes that it is a file-based URL. The solution is to just convert all image links to absolute in the form http://YOUR_DOMAIN/File/Image?path=Root/001.jpg.
You can also set a global property on the parser that works pretty much the same as the HTML <BASE> tag:
//Create a provider collection to set various processing properties
System.Collections.Generic.Dictionary<string, object> providers = new System.Collections.Generic.Dictionary<string, object>();
//Set the image base. This will be prepended to the SRC so watch your forward slashes
providers.Add(HTMLWorker.IMG_BASEURL, "http://YOUR_DOMAIN");
//Bind the providers to the worker
worker.SetProviders(providers);
worker.Parse(reader);
Below is a full working C# 2010 WinForms app targeting iTextSharp 5.1.2.0 that shows how to use a relative image and set its base using the global provider. Everything is pretty much the same as your code, although I through in a bunch of using statements to ensure proper cleanup. Make sure to watch the leading and trailing forward slashes on everything, the base URL gets prepended directly only the SRC attribute and you might end up with double-slashes if its not done correctly. I'm hard-balling a domain in here but you should be able to easily use the System.Web.HttpContext.Current.Request object.
using System;
using System.IO;
using System.Windows.Forms;
using iTextSharp.text;
using iTextSharp.text.html.simpleparser;
using iTextSharp.text.pdf;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
string html = #"<img src=""/images/home_mississippi.jpg"" />";
string outputFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "HtmlTest.pdf");
using (FileStream fs = new FileStream(outputFile, FileMode.Create, FileAccess.Write, FileShare.None)) {
using (Document doc = new Document(PageSize.TABLOID)) {
using (PdfWriter writer = PdfWriter.GetInstance(doc, fs)) {
doc.Open();
using (StringReader reader = new StringReader(html)) {
using (HTMLWorker worker = new HTMLWorker(doc)) {
//Create a provider collection to set various processing properties
System.Collections.Generic.Dictionary<string, object> providers = new System.Collections.Generic.Dictionary<string, object>();
//Set the image base. This will be prepended to the SRC so watch your forward slashes
providers.Add(HTMLWorker.IMG_BASEURL, "http://www.vendiadvertising.com");
//Bind the providers to the worker
worker.SetProviders(providers);
worker.Parse(reader);
}
}
doc.Close();
}
}
}
this.Close();
}
}
}