I am trying to use a PDFViewer in a SAPUI5 application, something like the following sample app.
When I try to use this component in Google chrome it will not load the data, however it is possible to download the PDF itself and it shows the url works and file is available.
If I open it in Firefox or IE it works!
I discussed the problem here with SAP OpenUI5 team. Finally we understood the problem is not the UI5 library and the problem is inside of our ABAP implementation that provides download link for the PDF file from SAP Document Management System (SAP DMS).
We finally found the solution and discovered why the pdf that we try to show from our SAP DMS is downloadable while it is not shown in the pdf viewer inside the modern browsers like Chrome or Firefox.
The source for the solution can find here.
The below two changes are different from normal implementation that can be found in most of the tutorials in the internet:
The header value must be changed to Inline;filename= instead of outline;filename.
Call the method /IWBEP/IF_MGW_CONV_SRV_RUNTIME=>Set_header to set the header.
Finally we have the following ABAP code in SAP systems for downloading files form document management system (SAP DMS).
"Logic for Download the files from Document Managmenet System
DATA: ls_lheader TYPE ihttpnvp,
ls_stream TYPE ty_s_media_resource,
ls_entity TYPE zgw_odata_document_file.
CONSTANTS: lc_headername TYPE string VALUE 'Content-Disposition',
lc_headervalue1 TYPE string VALUE 'inline; filename="',
lc_headervalue2 TYPE string VALUE '";'.
* "Get the name of the Entity
DATA(lv_entity_name) = io_tech_request_context->get_entity_type_name( ).
CASE lv_entity_name.
WHEN 'DocumentFile'.
DATA(lo_document_file) = NEW zcl_gw_odata_document_file( ).
lo_document_file->read_stream(
EXPORTING
it_key_tab = it_key_tab
IMPORTING
es_stream = ls_entity ).
ls_lheader-name = lc_headername.
ls_entity-file_name = escape( val = ls_entity-file_name format = cl_abap_format=>e_url ).
ls_lheader-value = lc_headervalue1 && ls_entity-file_name && lc_headervalue2 .
set_header( is_header = ls_lheader ).
ls_stream-mime_type = ls_entity-mimetype.
ls_stream-value = ls_entity-binfile.
copy_data_to_ref( EXPORTING is_data = ls_stream
CHANGING cr_data = er_stream ).
WHEN OTHERS.
ENDCASE.
Related
I have a requirement to add/update TOC - Table of Contents in MS document using OpenXML. I am facing challenges to achieve the same. I am using MS Office 2016.
I have tried all the options from this post:
How to generate Table Of Contents using OpenXML SDK 2.0?
Also gone through Eric White videos.
I am trying to use UpdateField option and able to add empty TOC following the sample code from the above link.
However when I open the document I am not getting a pop-up dialog which will ask to update the TOC.
Here is the sample code:
var sdtBlock = new SdtBlock();
sdtBlock.InnerXml = GetTOC(); //TOC Xml
document.MainDocumentPart.Document.Body.AppendChild(sdtBlock);
DocumentFormat.OpenXml.Wordprocessing.SimpleField f;
f = new SimpleField();
f.Instruction = "sdtContent";
f.Dirty = true;
document.MainDocumentPart.Document.Body.Append(f);
var setting = document.MainDocumentPart.DocumentSettingsPart;
if (setting != null)
{
document.MainDocumentPart.DocumentSettingsPart.Settings.Append(new UpdateFieldsOnOpen() { Val = new DocumentFormat.OpenXml.OnOffValue(true)});
document.MainDocumentPart.DocumentSettingsPart.Settings.Save();
}
It is displaying default message, whereas I have valid entries (Headings).
Is it due to MS Office 2016? UpdateField Pop-up is not coming?
I don't want to go with below options:
Word Automation - Due to Microsoft.Office.Interop.Word
Word Automation Services - Require Sharepoint for this
Adding Macro - As it is asking to save the document every time I open it.
Also let me know if there is any better option to create/update TOC.
Your answer/comment is really very helpful.
I have searched and searched and cannot find the answer to my problem. I've tried many different approaches in my code, but I've hit a wall and I'm not sure where to go from here. I seem to be wanting to do the same thing as these two threads:
Trying to insert an image into a pdf in c#
Add image in an existing PDF with itextsharp
They are very similar and the answer is the same. However, when I use that exact code, the result is a PDF without an image. Here is my code:
using (var existingFileStream = new FileStream(fileNameExisting, FileMode.Open))
using (var newFileStream = new FileStream(fileNameNew, FileMode.Create))
{
var pdfReader = new PdfReader(existingFileStream);
var stamper = new PdfStamper(pdfReader, newFileStream, '\0', true);
var form = stamper.AcroFields;
var fieldKeys = form.Fields.Keys;
foreach (var field in form.Fields)
{
if (field.Key == "form1[0].ec_Bldg_Photo_1[0].ImageField2[0]")
{
PushbuttonField imageField = form.GetNewPushbuttonFromField(field.Key);
imageField.Layout = PushbuttonField.LAYOUT_ICON_ONLY;
imageField.IconReference = null;
imageField.ProportionalIcon = true;
imageField.Image = Image.GetInstance(#"PATH_TO_IMAGE\front.jpg");
form.ReplacePushbuttonField(field.Key, imageField.Field);
}
}
stamper.FormFlattening = false;
stamper.Close();
pdfReader.Close();
}
I have tried to rule out all of the obvious things. My path to the image is correct, the field is indeed a PushbuttonField when I read the existing PDF field and get the field type. If I open the PDF in Adobe Reader and click on the placeholder for the image, it allows me to pick a file from my PC. When I place an image in the file, save, and then read in that PDF, I can then change my code to this:
imageField.ProportionalIcon = false;
And now all of sudden the image is stretched on the saved copy. So I see that it is changing this part but this is when I enter the image manually in Adobe Reader. When I read in the field after I set that image in Adobe Reader and it shows correctly, I see a couple interesting things. The field.Image property IS NULL and the field.IconReference is NOT NULL. When I use the original code to try and insert the image, it is reversed, where Image is NOT NULL but IconReference IS NULL
Any help would be greatly appreciated, thank you!!
EDIT 1: Ok so I didn't see it the first time, but I went back and checked more thoroughly and I did find that key. Here it is:
Several things are at play here.
Usage Rights:
The PDF is digitally signed with a private key owned by Adobe.
You can see this using RUPS here (in your screen shot you didn't go deep enough):
This has two implications:
The signature unlocks special permissions in Adobe Reader, such as the permission to save a filled out form locally.
Making any changes to the original PDF breaks the signature and removes the special permissions leading to an ugly error message in Adobe Reader.
This functionality is deprecated in (and even removed from) PDF 2.0. It's old technology that became obsolete with the emergence of PDF viewers other than Adobe Reader.
My suggestion: remove the usage rights to avoid breaking the signature. See the FAQ entry "Why do I get an error saying that "use of extended features is no longer available"?" iText 7 / iText 5
This is the iText 7 code:
public void removeUsageRights(PdfDocument pdfDoc) {
PdfDictionary perms = pdfDoc.getCatalog().getPdfObject().getAsDictionary(PdfName.Perms);
if (perms == null) {
return;
}
perms.remove(new PdfName("UR"));
perms.remove(PdfName.UR3);
if (perms.size() == 0) {
pdfDoc.getCatalog().remove(PdfName.Perms);
}
}
This is the iText 5 code:
PdfReader reader = new PdfReader(old_file);
if (reader.hasUsageRights()) {
reader.removeUsageRights();
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(new_file));
stamper.close();
}
reader.close();
This is the iText 5 answer.
Hybrid Form:
If you click on the /AcroForm entry, you see this:
There is a /Fields array with references to field dictionaries that are also widget annotations. That means that the document has an AcroForm form inside. However, there is also an /XFA entry with a series of XML snippets. That means that the document has an XFA form inside.
In other words: the same form description is added twice inside. You are changing a button in one form (the AcroForm part), but not in the other (the XFA form) and that leads to inconsistencies.
XFA has been deprecated in PDF 2.0 because there weren't many vendors supporting that technology. It's kind of frustrating to be confronted with forms that use deprecated technology.
My suggestion: I would remove the XFA part. See the FAQ entry "Is it safe to remove XFA?" iText 5 / iText 7
In iText 5, removing XFA is done like this:
AcroFields form = stamper.getAcroFields();
form.removeXfa();
Important: my suggestion is to remove all the deprecated functionality from the PDF, but if the government expects that functionality to be present, then you're out of luck. In that case, you will need to use Adobe software to process the form. If that's the case, you could complain to the government that their requirements lead to a de facto vendor lock-in. By the way: iText Software is also a vendor. It's an open source company that offers open source software under the AGPL license. The AGPL license allows free use under certain circumstances (see How do I make sure my software complies with AGPL: How can I use iText for free?) If you don't meet those requirements, you will have to purchase a commercial license for your use of iText.
Using SSJS I've successfully created a PDF using the simple HTML parser that comes with iText but the simple HTML parser doesn't respect CSS and is very limited. I downloaded the XMLWorker class from the iText site and have tried to use that instead but my knowledge of working out how to call Java packages is too limited. All the examples I can find use Java and refer to the classes directly, eg.
Document newPDF = new Document();
But in SSJS we have to use dot notation, eg.
var newPDF:com.itextpdf.text.Document = new com.itextpdf.text.Document();
This - I think - is where I stumble. My code looks like this:
function createLPO2(pReqDoc:NotesDocument) {
importPackage(com.itextpdf);
//importPackage(com.itextpdf.tool.xml.XMLWorkerHelper);
importPackage(java.io);
var con = facesContext.getExternalContext();
var response:com.ibm.xsp.webapp.XspHttpServletResponse = con.getResponse();
response.setContentType("application/pdf");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", -1);
response.setHeader("Content-Disposition","attachment; filename=\"LPO_" + pReqDoc.getItemValueString("RequisitionNo") + ".pdf\"");
var newPDF:com.itextpdf.text.Document = new com.itextpdf.text.Document();
var writer = com.itextpdf.text.pdf.PdfWriter.getInstance(newPDF,response.getOutputStream());
var xmlWorkerHelper = com.itextpdf.tool.xml.XMLWorkerHelper.getInstance();
var strHTML = getTestHTML(); //this is the HTML used in the examples on the iText site
xmlWorkerHelper.parseXHtml(writer, newPDF, new java.io.StringReader(strHTML));
newPDF.close();
writer.close();
facesContext.responseComplete();
}
If I run this script as it is I get a script error on the Domino console. If I remove the comment on the line importPackage(com.itextpdf.tool.xml.XMLWorkerHelper); it gives a completely different error. I suspect I have to import the XMLWorkerHelper package and not just the com.itextpdf package. I thought if I opened the jar file using a tool like 7-zip I could work out the path, which is how I arrived at com.itextpdf.tool.xml.XMLWorkerHelper
Is this right? If so, why does my script fail?
Rob,
seriously, don't try to do that in SSJS. iText is all Java, if you try to mangle with it in a different language it will stress you out. Create a wrapper class that has a method that takes an OutputStream and whatever data (Document, View etc) you need. Obtain the OutputStream in your SSJS and call the function. Look for the XAgent XSnippet on OpenNTF and my blog series (the last two are missing - bear with me) on PDF creation.
One word of caution: iText is GPL, so you either GPL your software too, buy a commercial iText license or look for alternatives like Apache PDFBox or Apache FOP. Ah the second caution: HTML to PDF is a Pita. You could look at a commercial tool like e.g. from Swing software (or change your approach)
I'm trying to generate a .pdf file using mPDF in a Zend Framework application, from the output of the action.
Here is the code of my action:
public function testAction()
{
$this->_helper->viewRenderer->setNoRender();
$this->_helper->layout->disableLayout();
$this->view->foo = 'bar';
$this->render();
$output = $this->getResponse()->getBody();
$layout = new Zend_Layout();
$layout->content = $output;
$layout->setLayoutPath(dirname(dirname(__FILE__)) . '/views/layouts/');
$layout->setViewSuffix('tpl');
$layout->setLayout('pdf');
$html = $layout->render();
$mpdf = new mPDF('utf-8', 'A4');
$mpdf->WriteHTML($html);
$mpdf->Output('report.pdf', 'D');
}
If the content to be displayed is long (i.e. a few paragraphs), when downloading the .pdf file, Adobe Reader throws the following error: Adobe Reader could not open 'report.pdf' because it is either not a supported file type or because the file has been damaged (for example, it was sent as an email attachment and wasn't correctly decoded).
However, if I pass the same output to mpdf as a static variable, without using Zend Layout render, then the .pdf file opens without any errors. Also, Adobe Reader throws the issue if and only if the content is long (i.e. it works if there are only a couple of words).
Is there any limit I should be aware of?
there should not be space at beginning and at the end of file so check these space,
Adobe Reader is less forgiving than some othe PDF readers if the PDF file is corrupt. Open your PDF document in a text editor and check that the file starts with something like:
%PDF-1.4
%âãÃÓ
Sometimes PHP error notices are found at the top of the file.
Source : mpdf forum IanBack's answer
I'm trying to query QBO for, among other entities, Accounts, and am running into a couple of issues. I'm using the .Net Dev Kit v 2.1.10.0 (I used NuGet to update to the latest version) and when I use the following technique:
Intuit.Ipp.Data.Qbo.AccountQuery cquery = new Intuit.Ipp.Data.Qbo.AccountQuery();
IEnumerable<Intuit.Ipp.Data.Qbo.Account> qboAccounts = cquery.ExecuteQuery<Intuit.Ipp.Data.Qbo.Account>(context);
(i.e. just create a new AccountQuery of the appropriate type and call ExecuteQuery) I get an error. It seems that the request XML is not created properly, I just see one line in the XML file. I then looked at the online docs and tried to emulate the code there:
Intuit.Ipp.Data.Qbo.AccountQuery cquery = new Intuit.Ipp.Data.Qbo.AccountQuery();
cquery.CreateTime = DateTime.Now.Date.AddDays(-20);
cquery.SpecifyOperatorOption(Intuit.Ipp.Data.Qbo.FilterProperty.CreateTime,
Intuit.Ipp.Data.Qbo.FilterOperatorType.AFTER);
cquery.CreateTime = DateTime.Now.Date;
cquery.SpecifyOperatorOption(Intuit.Ipp.Data.Qbo.FilterProperty.CreateTime,
Intuit.Ipp.Data.Qbo.FilterOperatorType.BEFORE);
// Specify a Request validator
Intuit.Ipp.Data.Qbo.AccountQuery cquery = new Intuit.Ipp.Data.Qbo.AccountQuery();
IEnumerable<Intuit.Ipp.Data.Qbo.Account> qboAccounts = cquery.ExecuteQuery<Intuit.Ipp.Data.Qbo.Account>(context);
unfortunately, VS 2010 insists that AccountQuery doesn't contain a definition for SpecifyOperatorOption and there is no extension method by that name. So I'm stuck.
Any ideas how to resolve this would be appreciated.