jasper reports with HTML Format - jasper-reports

Am using jasper reports library with GWT application.
The reports is generated well with CSV format but with HTML format it generate the HTML page with icons of missing picture.
I know that jasper using transparent image called "PX", this image not found.
How can i solve this problem?
Thanks in Advance

If you don't have images to show then you can do this:
JasperPrint jasperPrint = JasperFillManager.fillReport(path, parameters, con);
JRHtmlExporter htmlExporter = new JRHtmlExporter();
response.setContentType("text/html");
request.getSession().setAttribute(ImageServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE, jasperPrint);
htmlExporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
htmlExporter.setParameter(JRExporterParameter.OUTPUT_WRITER, out);
htmlExporter.setParameter(JRHtmlExporterParameter.IS_USING_IMAGES_TO_ALIGN, false);
htmlExporter.exportReport();
The important line is this one:
htmlExporter.setParameter(JRHtmlExporterParameter.IS_USING_IMAGES_TO_ALIGN, false);
That will make all the "px" images disappear.

Try passing in your image as a parameter to the report so you won't have to worry about image paths.
You can set the type of the parameter as a BufferedImage or whatever image class suits.

My solution was to use data URIs. This isn't very elegant since it bloats the size of the HTML and doesn't work in IE prior to IE8, but it does allow you to not bother worrying about creating files out of the image attachments Jasper sends you either.
If you're going to implement this, you want to add this argument to your request:
<argument name="IMAGES_URI"><![CDATA[data:]]></argument>
Then you need to parse the report HTML that JasperServer sends back:
foreach ($attachments as $name => $attachment) {
// Cut off the cid: portion of the name.
$name = substr($name, 4);
// Replace any image URIs with a data: uri.
if (strtolower(substr($name, 0, 4)) !== 'uuid' && strtolower($name) !== 'report') {
if (strtoupper(substr($attachment, 0, 3)) === 'GIF') {
// It's a GIF.
$report = str_replace("data:$name", 'data:image/gif;base64,' . base64_encode($attachment), $report);
} elseif (/* more file type tests */) {
// and so on...
}
}
}
For large images, it's best to do as Gordon suggested and pass in a parameter specifying the URL of a file that is permanently stored on the server. This method is more of a failsafe for gracefully handling any unexpected images JasperServer tries throwing at you.

I'm a bit late to this discussion but this is what I've been using. The key is to pass the imagesMap to both the session attribute and exporter parameter, and to set the IMAGES_URI exporter parameter.
private void exportReportAsHtml(HttpServletRequest request, HttpServletResponse response, JasperPrint jasperPrint) throws IOException, JRException {
response.setContentType("text/html");
request.getSession().setAttribute(ImageServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE, jasperPrint);
Map imagesMap = new HashMap();
request.getSession().setAttribute("IMAGES_MAP", imagesMap);
JRHtmlExporter exporter = new JRHtmlExporter();
exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
exporter.setParameter(JRExporterParameter.OUTPUT_WRITER, response.getWriter());
exporter.setParameter(JRHtmlExporterParameter.IMAGES_MAP, imagesMap);
exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI, "image?image=");
exporter.exportReport();
}

Related

How to get values and the keys of all the controls in a dynamic pdf using iText?

I've tried to extract all the fields out of a dynamic form. But I've observed that the code worked for some forms while not for others. Worst, the code worked differently for the same form but two different downloaded files. But after digging a lot, I found that those forms which correctly, were freshly processed. Not even a single details were filled from a PDF Software(Adobe Reader). Also, if the form was filled and saved the thumbnail of the form in the explorer would change from. The code snippet is as follows:
PdfDocument pdfDoc;
pdfDoc = new PdfDocument(new PdfReader(src), new PdfWriter(dest));
PdfDictionary perms = pdfDoc.getCatalog().getPdfObject().getAsDictionary(PdfName.Perms);
if (perms != null) {
perms.remove(new PdfName("UR"));
perms.remove(PdfName.UR3);
if (perms.size() == 0) {
pdfDoc.getCatalog().remove(PdfName.Perms);
}
}
PdfAcroForm form = PdfAcroForm.getAcroForm(pdfDoc, true);
List<String> result = new ArrayList<String>(form.getFormFields().keySet());
Map<String, PdfFormField> fields = form.getFormFields();
Below is the image for the same form, but downloaded twice. The one with the colorful thumbnail is not filled. Other is filled using Adobe Reader and saved, and on saving the thumbnail vanished.
I suspect a flag might get set on saving the form. Any help is appreciated.Another peculiar observation, there was a mismatch in the number of parameters in the PdfCatalog object for the above two forms. An entry for the property 'NeedsRendering' was present in the faulty PDF and otherwise for the working PDf. I've attached screenshots for the working PDF during a debugging session.
hrsa_working_form:
Update 1
#Browno, apologies for the confusing question from a newbie's mind. I've posted the screenshots from the itext RUPS for the key '/AcroForm'. On exploring the answers for XFAForm, I've learned how to fill them. But flattening them causes an exception. I've used the pdfxfa jar under the license of AGPL. I'm lacking the knowledge of XFAFlattener and it's properties used in the XFAFlattenerProperties class. Below is the code snapshot:
public void fillData2(String src, String xml, String dest, String newDest){
throws IOException, ParserConfigurationException, SAXException, InterruptedException {
PdfReader reader = new PdfReader(src);
reader.setUnethicalReading(true);
PdfDocument pdfDoc = new PdfDocument(reader, new PdfWriter(dest), new StampingProperties().useAppendMode());
PdfAcroForm form = PdfAcroForm.getAcroForm(pdfDoc, true);
List<String> result = new ArrayList<String>(form.getFormFields().keySet());
System.out.println(result.size());
XfaForm xfa = form.getXfaForm();
xfa.fillXfaForm(new FileInputStream(xml));
xfa.write(pdfDoc);
//form.flattenFields(); throws exception
pdfDoc.close();
FileInputStream fis = new FileInputStream(dest);
FileOutputStream fos = new FileOutputStream(newDest);
XFAFlattener xfaFlattener = new XFAFlattener();
xfaFlattener.setFontSettings(new XFAFontSettings().setEmbedExternalFonts(true));
xfaFlattener.flatten(fis, fos);
fis.close();
fos.close();
}
The encountered exception is:
Exception in thread "main" java.lang.NoSuchFieldError: FONTFAMILY
at com.itextpdf.tool.xml.xtra.xfa.font.XFAFontProvider.addFonts(XFAFontProvider.java:117)
at com.itextpdf.tool.xml.xtra.xfa.font.XFAFontProvider.<init>(XFAFontProvider.java:56)
at com.itextpdf.tool.xml.xtra.xfa.XFAFlattener.initFlattener(XFAFlattener.java:643)
at com.itextpdf.tool.xml.xtra.xfa.XFAFlattener.flatten(XFAFlattener.java:201)
at com.itextpdf.tool.xml.xtra.xfa.XFAFlattener.flatten(XFAFlattener.java:396)
at com.mycompany.kitext.kitext.fillData2(kitext.java:153)
at com.mycompany.kitext.kitext.main(kitext.java:81)
Also, as per #mkl's comment, I've attached the PDF forms:
https://drive.google.com/file/d/0B6w278NcMSCrZDZoZklmVTNuOWc/view?usp=sharing
//iText RUPS /AcroForm Snapshot
https://drive.google.com/file/d/0B6w278NcMSCrZ1Q1VHc5YzY4UG8/view?usp=sharing
//Form filled with fillXfaForm()
//running low on reputation
Form filled with XFA
I've also read the pdfXFA Release notes for developers. But couldn't find a similar example. Thanks for your help and the great work on iText.

Arabic problems with converting html to PDF using ITextRenderer

When I use ITextRenderer converting html to PDF.this is my code
ByteArrayOutputStream out = new ByteArrayOutputStream();
ITextRenderer renderer = new ITextRenderer();
String inputFile = "C://Users//Administrator//Desktop//aaa2.html";
String url = new File(inputFile).toURI().toURL().toString();
renderer.setDocument(url);
renderer.getSharedContext().setReplacedElementFactory(
new B64ImgReplacedElementFactory());
// 解决阿拉伯语问题
ITextFontResolver fontResolver = renderer.getFontResolver();
try {
fontResolver.addFont("C://Users//Administrator//Desktop//arialuni.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
} catch (DocumentException e) {
e.printStackTrace();
}
renderer.layout();
OutputStream outputStream = new FileOutputStream("C://Users//Administrator//Desktop//HTMLasPDF.pdf");
renderer.createPDF(outputStream, true);
/*PdfWriter writer = renderer.getWriter();
writer.open();
writer.setRunDirection(PdfWriter.RUN_DIRECTION_RTL);
OutputStream outputStream2 = new FileOutputStream( "C://Users//Administrator//Desktop//HTMLasPDFcopy.txt");
renderer.createPDF(outputStream2);*/
renderer.finishPDF();
out.flush();
out.close();
Actual PDF Result:
Expected PDF Result:
How to make arabic ligature?
If you want to do this properly (I assume using iText, since your post is tagged as such), you should use
iText7
pdfHTML (to convert HTML to PDF)
pdfCalligraph (to handle Arabic ligatures properly)
a font that supports these features (as indicated by another answer)
For an example, please consult the HTML to PDF tutorial, more specifically the following FAQ item: How to convert HTML containing Arabic/Hebrew characters to PDF?
You need fonts that contain the glyphs you need, e.g.:
public static final String[] FONTS = {
"src/main/resources/fonts/noto/NotoSans-Regular.ttf",
"src/main/resources/fonts/noto/NotoNaskhArabic-Regular.ttf",
"src/main/resources/fonts/noto/NotoSansHebrew-Regular.ttf"
};
And you need a FontProvider that knows how to find these fonts in the ConverterProperties:
public void createPdf(String src, String[] fonts, String dest) throws IOException {
ConverterProperties properties = new ConverterProperties();
FontProvider fontProvider = new DefaultFontProvider(false, false, false);
for (String font : fonts) {
FontProgram fontProgram = FontProgramFactory.createFont(font);
fontProvider.addFont(fontProgram);
}
properties.setFontProvider(fontProvider);
HtmlConverter.convertToPdf(new File(src), new File(dest), properties);
}
Note that the text will come out all wrong if you don't have the pdfCalligraph add-on. That add-on didn't exist at the time Flying Saucer was created, hence you can't use Flying Saucer for converting documents with text in Arabic, Hindi, Telugu,... Read the pdFCalligraph white paper if you want to know more about ligatures.
Greek characters seemed to be omitted; they didn’t show up in the document.
In flying saucer the generated PDF uses some kind of default
(probably Helvetica) font, that contains a very limited character set,
that obviously does not contain the Greek code page. link
I change the way to convert pdf by using wkhtmltopdf.

How to edit pasted content using the Open XML SDK

I have a custom template in which I'd like to control (as best I can) the types of content that can exist in a document. To that end, I disable controls, and I also intercept pastes to remove some of those content types, e.g. charts. I am aware that this content can also be drag-and-dropped, so I also check for it later, but I'd prefer to stop or warn the user as soon as possible.
I have tried a few strategies:
RTF manipulation
Open XML manipulation
RTF manipulation is so far working fairly well, but I'd really prefer to use Open XML as I expect it to be more useful in the future. I just can't get it working.
Open XML Manipulation
The wonderfully-undocumented (as far as I can tell) "Embed Source" appears to contain a compound document object, which I can use to modify the copied content using the Open XML SDK. But I have been unable to put the modified content back into an object that lets it be pasted correctly.
The modification part seems to work fine. I can see, if I save the modified content to a temporary .docx file, that the changes are being made correctly. It's the return to the clipboard that seems to be giving me trouble.
I have tried assigning just the Embed Source object back to the clipboard (so that the other types such as RTF get wiped out), and in this case nothing at all gets pasted. I've also tried re-assigning the Embed Source object back to the clipboard's data object, so that the remaining data types are still there (but with mismatched content, probably), which results in an empty embedded document getting pasted.
Here's a sample of what I'm doing with Open XML:
using OpenMcdf;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
...
object dataObj = Forms.Clipboard.GetDataObject();
object embedSrcObj = dateObj.GetData("Embed Source");
if (embedSrcObj is Stream)
{
// read it with OpenMCDF
Stream stream = embedSrcObj as Stream;
CompoundFile cf = new CompoundFile(stream);
CFStream cfs = cf.RootStorage.GetStream("package");
byte[] bytes = cfs.GetData();
string savedDoc = Path.GetTempFileName() + ".docx";
File.WriteAllBytes(savedDoc, bytes);
// And then use the OpenXML SDK to read/edit the document:
using (WordprocessingDocument openDoc = WordprocessingDocument.Open(savedDoc, true))
{
OpenXmlElement body = openDoc.MainDocumentPart.RootElement.ChildElements[0];
foreach (OpenXmlElement ele in body.ChildElements)
{
if (ele is Paragraph)
{
Paragraph para = (Paragraph)ele;
if (para.ParagraphProperties != null && para.ParagraphProperties.ParagraphStyleId != null)
{
string styleName = para.ParagraphProperties.ParagraphStyleId.Val;
Run run = para.LastChild as Run; // I know I'm assuming things here but it's sufficient for a test case
run.RunProperties = new RunProperties();
run.RunProperties.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Text("test"));
}
}
// etc.
}
openDoc.MainDocumentPart.Document.Save(); // I think this is redundant in later versions than what I'm using
}
// repackage the document
bytes = File.ReadAllBytes(savedDoc);
cf.RootStorage.Delete("Package");
cfs = cf.RootStorage.AddStream("Package");
cfs.Append(bytes);
MemoryStream ms = new MemoryStream();
cf.Save(ms);
ms.Position = 0;
dataObj.SetData("Embed Source", ms);
// or,
// Clipboard.SetData("Embed Source", ms);
}
Question
What am I doing wrong? Is this just a bad/unworkable approach?

ExcelSoftArtisans - Bug on Save method with open Stream - Cannot accessed closed file

I have the following issue:
I’m doing an export of an ASP.Net GridView directly to an excel file.
I’m setting an image as a header in this method:
private static void insertPageHeaderFooter(ExcelInterfaceSoftArtisans excel,DateTime generatedDateTime)
{
StringBuilder builderFooterLeft = new StringBuilder();
builderFooterLeft.Append("&08Comfone AG Tel: +41 31 341 10 10");
builderFooterLeft.Append("\r");
builderFooterLeft.Append("&08Nussbaumstrasse 25 Fax: +41 31 341 10 11");
builderFooterLeft.Append("\r");
builderFooterLeft.Append("&08CH-3000 Bern 22 www.comfone.com");
StringBuilder builderFooterRight = new StringBuilder();
String sDateTime = generatedDateTime.ToString(CultureInfoHandler.ShortDateShortTimeFormat);
builderFooterRight.Append("&08&F");
builderFooterRight.Append("\r");
builderFooterRight.Append(string.Format("&08 {0}", sDateTime));
builderFooterRight.Append("\r"); //new line
builderFooterRight.Append("&08Page &P of &N");
excel.SetHeader("&G", 0.6, HeaderFooterSection.Section.Left, false);
excel.SetFooter(builderFooterLeft.ToString(), HeaderFooterSection.Section.Left, false);
excel.SetFooter(builderFooterRight.ToString(), HeaderFooterSection.Section.Right, false);
}
protected void SetHeader(string sText, double dImageSizeFactor, HeaderFooterSection.Section section, Worksheet sheet)
{
string headerAbsolutePath = HttpContext.Current.Server.MapPath("~/Resources/Mandates/CHECF.png");
Stream imageStream = new FileStream(headerAbsolutePath, FileMode.Open, FileAccess.Read);
Size imageSize = Image.FromStream(imageStream).Size;
imageStream = new FileStream(headerAbsolutePath, FileMode.Open, FileAccess.Read);
HeaderFooterSection header = sheet.PageSetup.GetHeader(section);
header.SetContent(sText, imageStream);
header.SetContent(sText);
header.GetPicture().Height = (int)(imageSize.Height * dImageSizeFactor);
header.GetPicture().Width = (int)(imageSize.Width * dImageSizeFactor);
imageStream.Close();
}
As you can see on the last line, I close the Stream.
Now, I want to save my excel file this way:
HttpContext.Current.Response.ClearContent();
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.ClearHeaders();
excel.SaveWorkbook(sFileName, HttpContext.Current.Response, false);
/// <summary>
/// Saves the current Workbook under the given filename
/// </summary>
/// <param name="filename"></param>
/// <param name="response"></param>
/// <param name="openInBrowser"></param>
public void SaveWorkbook(string filename, HttpResponse response, bool openInBrowser)
{
if (book != null)
{
application.Save(book, response, filename, openInBrowser);
}
}
but when I close the stream in the SetHeader method, I get the following error:
Error Message: Cannot access a closed file.
Stack Trace: at System.IO.__Error.FileNotOpen()
at System.IO.FileStream.Seek(Int64 offset, SeekOrigin origin)
and when I don’t close the stream in the SetHeader method, the file is correctly saved.
Are you aware of this bug? How is it possible that I need to have an open stream in order to save an excel file? What can I do to fix that?
I’m attaching you the whole classes I’m using, so you can identify the problem better.
Thanks for your quick answer and solution on this problem.
[Disclaimer: I am the product owner of OfficeWriter]
This issue has been confirmed as a bug and has been submitted to the OfficeWriter development team.
In the meantime, I would recommend Sam's suggested workaround of using the overload that takes the image's file path instead of the image stream.
Here is a generic code snippet for how to insert an image into the header of an Excel file using the file path overload of HeaderFooterSection.SetContent():
//Open the workbook and get a handle on the worksheet that will contain the
//image in the header
ExcelApplication xla = new ExcelApplication();
Workbook wb = xla.Open(Page.MapPath("\\template.xlsx"));
Worksheet ws = wb.Worksheets["Sheet1"];
//Set the header
HeaderFooterSection header = ws.PageSetup.GetHeader(HeaderFooterSection.Section.Left);
header.SetContent("&G", Page.MapPath("\\images\\image1.png"));
Please see our documentation for additional reference on the SetContent() overloads and using ExcelWriter to format headers and footers in workbooks.
This issue has been addressed in the recent 8.5.1 release of OfficeWriter. See the change log.

Varying pagination in different formats of a report

Using iReport, I am generating reports to be viewed in multiple formats. Is it possible for me to ignore pagination only for particular formats like HTML and let it be true for the rest?
With isIgnorePagination="false" the HTML preview appears in chunks. However, setting it to true makes the PDF output a single page.
Any suggestions?
Why yes you can. Add the the IS_IGNORE_PAGINATION with the appropriate value before you export your report. You can set the value at run time based on what your export format is.
params.put("IS_IGNORE_PAGINATION", true);
I found one solution for this problem:
paramaters.put("fromDate", fromDate);
paramaters.put("toDate", toDate);
if (!output.equals("pdf"))
{
paramaters.put("IS_IGNORE_PAGINATION", true);
}
else
paramaters.put("IS_IGNORE_PAGINATION", false);
JasperPrint jasperPrint = null;
jasperPrint = JasperFillManager.fillReport(CompiledReport, paramaters, connection);
if (output.equals("html")) {
generateHtmlResponse(response, jasperPrint);
} else if (output.equals("pdf")) {
generatePdfResponse(response, jasperPrint);
} else if(output.equals("excel")) {
generateXLResponse(response, jasperPrint);
}