I have a multi-format document viewer, in which, for displaying PDFs, I use PF Extension's p:documentViewer component. The backing bean that supplies the StreamedContent of the PDF is phase rendered and is working as expected. However, though the PDF itself gets rendered fine, the viewer doesn't display the digital signatures in it. Do I need to add any extra configurations to the p:documentViewer while using it? Here is my usage of it:
<pe:documentViewer id="pdfVw" height="600" width="800" value="#{viewerController4.pdfDocumentStream}">
<f:param name="id" value="#{viewerController4.currentDocId}" />
</pe:documentViewer>
The backing bean method serving the content of the PDF:
public StreamedContent getPdfDocumentStream() throws IOException {
FacesContext context = FacesContext.getCurrentInstance();
if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
return new DefaultStreamedContent();
} else {
String id = context.getExternalContext().getRequestParameterMap().get("id");
Doc doc = pdfDocMap.get(id);
return new DefaultStreamedContent(new FileInputStream(new File(doc.getDocPath())), "application/pdf", doc.getDocName());
}
}
Incidentally, I also have a feature on the UI, to display thumbnails of documents -- in which, for PDFs, I extract the first page using PDFBox and convert that into a PNG image and display within a p:graphicImage. I observe, that in this image, the digital signature is displayed fine!
I'm on SpringBoot + PF 6.2 + JoinFaces
If you need to display PDF with digital signatures PDF.js does not support it currently and the ticket has been open since 2012.
See: https://github.com/mozilla/pdf.js/issues/1076
I suggest you use these service which is free and runs in the browser to show PDF's with signatures: https://verify.ink/
Related
I created a document file from word and has exported as pdf . i want to show the pdf content inside the Div element in razor page. How can I show the pdf content from razor page. Please can you provide an example code how to show in blazor server side
If you stored your pdf file directly in your documents for example in the folder wwwroot/pdf.
wwwroot/pdf/test.pdf
You can display this PDF with this line of html bellow :
< embed src="pdf/test.pdf" style="width=100%; height=2100px;" />
It will provide you a pdf displayer with printing options !
If you want to go further, upload your file and then display it, I will recommend you to go check this explanation :
https://www.learmoreseekmore.com/2020/10/blazor-webassembly-fileupload.html
The upload for PDF files works the same as Img file, you need to go check IBrowserFile documentation.
You will see that it has a Size obj and a OpenReadStream() function that will help you get the display Url for your file (image or pdf)
If the site abow closes, this is the upload code that is shown on it :
#code{
List<string> imgUrls = new List<string>();
private async Task OnFileSelection(InputFileChangeEventArgs e)
{
foreach (IBrowserFile imgFile in e.GetMultipleFiles(5))
{
var buffers = new byte[imgFile.Size];
await imgFile.OpenReadStream().ReadAsync(buffers);
string imageType = imgFile.ContentType;
string imgUrl = $"data:{imageType};base64,{Convert.ToBase64String(buffers)}";
imgUrls.Add(imgUrl);
}
}
}
This code was written by Naveen Bommidi, author of the blog where I found this usefull code
If you want, as I said, upload a PDF and then display it.
You can use the same html line :
< embed src="#imgUrl" style="width=100%; height=2100px;" />
And your uploaded files will be displaying.
Example
I'm trying to save an html document to PDF using flyingsaucer but the generated document always ends up having an A4 dimension when I look at the Document Properties from Adobe Reader (Page Size: 8.26 x 11.69 in).
I did read the documentation and I'm passing the css #page {size: letter;} style. And while it does have an effect on the output, the page size always remains 8.26 x 11.69 in Adobe Reader. For example, if I set the page size to legal, my PDF is still the size of a A4 but the top of the document is missing as if it had fell off the "paper".
I'm not sure if the problem falls on the itext side or the flying saucer side. I was using a fairly old version so my first step was to upgrade to the latest 9.1.6 version of flying saucer. I also moved from itext 2.0.8 to openPDF 1.0.1 but I'm still getting the same behavior.
I also traced in the debugger up to the com.lowagie.text.Document creation in ITextRenderer and at this point the document size passed is correct. That makes me think that the issue might be in openPDF / iText but I can't find what I'm doing wrong.
It turns out the PDF generation was correctly using the #page size declaration and the problem was occurring later in our software. What I had not noticed is that after the generation of the PDF another method was called to merge multiple PDFs into one. This method should probably not have been called, but that's another story.
The bottom line is this method created a new com.lowagie.text.Document(), which by default creates an A4 sized document, and then was iterating over all pages of the pdf, adding the pages to the new document using pdfWriter.getImportedPage(pdfReader, currentPage++). These imported pages did not retain their original size.
I fixed it by passing the page size of the fist page when creating the merged document object:
document = new Document(pdfReader.getPageSize(1));
The real problem is that you're (unwittingly) using software that is no longer supported. Anything that still has the namespace lowagie (the founder and CTO of iText) is really outdated.
If you simply want to convert HTML to pdf, why not use iText directly and cut out the middle-man?
We have multiple options for you.
XMLWorker (iText5 based code that converts HTML to pdf)
pdfHTML (iText7 based add-on that converts HTML5/CSS3 to pdf)
This is a rather extensive code-sample for using pdfHTML:
public void createPdf(String src, String dest, String resources) throws IOException {
try {
FileOutputStream outputStream = new FileOutputStream(dest);
WriterProperties writerProperties = new WriterProperties();
//Add metadata
writerProperties.addXmpMetadata();
PdfWriter pdfWriter = new PdfWriter(outputStream, writerProperties);
PdfDocument pdfDoc = new PdfDocument(pdfWriter);
pdfDoc.getCatalog().setLang(new PdfString("en-US"));
//Set the document to be tagged
pdfDoc.setTagged();
pdfDoc.getCatalog().setViewerPreferences(new PdfViewerPreferences().setDisplayDocTitle(true));
//Set meta tags
PdfDocumentInfo pdfMetaData = pdfDoc.getDocumentInfo();
pdfMetaData.setAuthor("Joris Schellekens");
pdfMetaData.addCreationDate();
pdfMetaData.getProducer();
pdfMetaData.setCreator("iText Software");
pdfMetaData.setKeywords("example, accessibility");
pdfMetaData.setSubject("PDF accessibility");
//Title is derived from html
// pdf conversion
ConverterProperties props = new ConverterProperties();
FontProvider fp = new FontProvider();
fp.addStandardPdfFonts();
fp.addDirectory(resources);//The noto-nashk font file (.ttf extension) is placed in the resources
props.setFontProvider(fp);
props.setBaseUri(resources);
//Setup custom tagworker factory for better tagging of headers
DefaultTagWorkerFactory tagWorkerFactory = new AccessibilityTagWorkerFactory();
props.setTagWorkerFactory(tagWorkerFactory);
HtmlConverter.convertToPdf(new FileInputStream(src), pdfDoc, props);
pdfDoc.close();
} catch (Exception e) {
e.printStackTrace();
}
}
You can find more information at http://itextpdf.com/itext7/pdfHTML
I am using PDFBox to extract text from my PDF document. It retrieves the text, but not all of it (specifically, seems like title/header and footer texts are missing). The parts that are missing are not images and are extracted when using text view in foxit reader.
I am using version 1.8.12 and made a test case with 2.0.2 just to see if it would return more of the content.
This is the code i used for 2.0.2:
public static void main(String[] args) {
File file = new File("D:\\\\file.pdf");
try {
PDDocument doc = PDDocument.load(file);
PDFTextStripper stripper = new PDFTextStripper();
//stripper.setSuppressDuplicateOverlappingText(false);
stripper.getText(doc);
} catch (Exception e) {
System.out.println("Exc errirs ");
}
}
Now I wonder are there any settings I missed? Is PDFBox failing because text is on top of some decorative elements (rectangle under text)?
Thanks
EDIT: link to file in question
As discussed in the comments, the text wasn't missing, but at the "wrong" position. By default, PDFBox text extraction extracts the characters as they come in the content stream, but they don't always come in a "natural" way. PDF files are created by software, not by humans.
An alternative is to use the sort option:
stripper.setSortByPosition(true)
However, as mkl pointed out, if the text is in two columns, you won't like the result either.
I have a requirement in which I have to generate a pdf and then on click of button "SHOW PDF", I have to display on another window.
I have been able to generate a pdf using IText and stored in my machine. I get a java.io.File object as my return value from my backend library which needs to be displayed on the screen. Can someone please guide me how to do this?
My xhtml file has the following code snippet:
<h:commandLink action="PdfDisplayRedirect.xhtml" target="_blank">show PDF</h:commandLink>
my PdfDisplayRedirect.xhtml has the following code:
<p:media value="#{pdfGenerationAction.fileName}" width="100%" height="300px">
Your browser can't display pdf, <h:outputLink value="InitialExamination33.pdf">click</h:outputLink> to download pdf instead.
My backing bean has the following code:
private File initialExaminationFile;
private generateFile(){
this.initialExaminationFile = backendService.generateFile();
}
On clicking, I get a new window opened but the pdf file is not displayed.. Instead my screen from where I had invoked the command gets displayed there.
Any help would be really appreciated.
Thanks
Thanks for the response and no response.
I have found a solution myself which I would like to post so that those looking for a solution can use it.
My xhtml file included a commandlink
<p:commandLink actionListener="#{pdfGenerationAction.generatePDF(initialExaminationEMRAction.patientID)}" oncomplete="window.open('PdfDisplayRedirect.xhtml')">broadcast Msg</p:commandLink>
My pdfGenerationAction bean file had the following lines of code:
FileInputStream fis = new FileInputStream(this.initialExaminationFile);
//System.out.println(file.exists() + "!!");
//InputStream in = resource.openStream();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
try {
for (int readNum; (readNum = fis.read(buf)) != -1;) {
bos.write(buf, 0, readNum); //no doubt here is 0
//Writes len bytes from the specified byte array starting at offset off to this byte array output stream.
System.out.println("read " + readNum + " bytes,");
}
this.reportBytes = buf;
}
I converted my file into bytearraystream and made it available in my session. Then I followed the suggestion given by BalusC at Unable to show PDF in p:media generated from streamed content in Primefaces
Can anyone help me in displaying PDF document in JSF page in iframe only?
Thanks in advance,
Suresh
Just use <iframe> the usual way:
<iframe src="/path/to/file.pdf"></iframe>
If your problem is rather that the PDF is not located in the WebContent, but rather located somewhere else in disk file system or even in a database, then you basically need a Servlet which gets an InputStream of it and writes it to the OutputStream of the response:
response.reset();
response.setContentType("application/pdf");
response.setContentLength(file.length());
response.setHeader("Content-disposition", "inline; filename=\"" + file.getName() + "\"");
BufferedInputStream input = null;
BufferedOutputStream output = null;
try {
input = new BufferedInputStream(new FileInputStream(file), DEFAULT_BUFFER_SIZE);
output = new BufferedOutputStream(response.getOutputStream(), DEFAULT_BUFFER_SIZE);
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int length;
while ((length = input.read(buffer)) > 0) {
output.write(buffer, 0, length);
}
} finally {
close(output);
close(input);
}
This way you can just point to this servlet instead :) E.g.:
<iframe src="/path/to/servlet/file.pdf"></iframe>
You can find a complete example of a similar servlet in this article.
The <iframe> also works fine in JSF, assuming that you're using JSF 1.2 or newer. In JSF 1.1 or older you have to wrap plain vanilla HTML elements such as <iframe> inside a <f:verbatim> so that they will be taken into the JSF component tree, otherwise they will be dislocated in the output:
<f:verbatim><iframe src="/path/to/servlet/file.pdf"></iframe></f:verbatim>
I recommend you to have a look at http://www.jpedal.org/. You can convert each of the pdf pages to images and deliver them separately to the browser.
This approach is more secure for your application, since the pdf is never send to the client.