Script File is not executed in PDF file - javascript

I am still new to Syncfusion. Currenly I've done a table with a script (document.ready) function to merge the table cells with similar values. The table have been displayed on Google Chrome successfully with my localhost and the columns of the table containing similar values have been merged successfully as well. A function of generating the webpage to PDF works successfully, but the columns of the table displayed on the PDF file do not merge, so I assume that the script file is not rendered in my PDF function.
This is my PDF Function:
private void printpdf()
{
//printpdf
//Initialize HTML to PDF converter
HtmlToPdfConverter htmlConverter = new HtmlToPdfConverter(HtmlRenderingEngine.WebKit);
WebKitConverterSettings settings = new WebKitConverterSettings();
//Set WebKit path
settings.WebKitPath = Server.MapPath("~/QtBinaries");
settings.EnableJavaScript = true;
settings.AdditionalDelay = 5000;
//Assign WebKit settings to HTML converter
htmlConverter.ConverterSettings = settings;
//Get the current URL
string url = HttpContext.Current.Request.Url.AbsoluteUri;
//Convert URL to PDF
Syncfusion.Pdf.PdfDocument document = htmlConverter.Convert(url);
//Save the document
document.Save("Output.pdf", HttpContext.Current.Response, HttpReadType.Save);
}
This is my Script Function on aspx file:
$(document).ready(function () {
-
-
-
};

The webKit rendering engine will preserve the PDF document like how the input HTML file displayed on WebKit (example, safari) based web browsers. So, kindly ensure the preservation of your webpage on WebKit based browser. If it is not possible, kindly share with us the complete HTML file (save the webpage from a web browser and share the complete HTML file with styles, scripts, etc.,) to us. So, that it will be helpful for us to analyze and assist you further on this.
If your web page is rendering properly in the chrome browser, kindly try our latest Blink rendering engine for the conversion. It will preserve the output PDF document like how the input HTML is displayed on chromium-based browsers. Please refer below link for more information,
https://help.syncfusion.com/file-formats/pdf/convert-html-to-pdf/blink
https://www.syncfusion.com/kb/10258/how-to-convert-html-to-pdf-in-azure-using-blink

Related

How to get custom ttf font working with jsPDF.output()

I've added the jsPDF library to my Titanium project to generate PDFs client side, which has been working great. But now I want to localize the app for Arabic countries, which means that I have the add a custom font. This works perfectly if you use doc.save('file.pdf'), but it doesn't seem to work correctly for doc.output(). I have to use output because I'm using jsPDF outside of a browser.
To make the library work in Titanium I've had to strip all of the references to window, because it's not running in a browser or webview.
I've tried writing the file from different sources, but nothing seems to yield any results.
My current implementation:
doc = new jsPDF();
var f = Ti.Filesystem.getFile(Ti.Filesystem.resourcesDirectory, 'fonts/markazi-text.regular.ttf');
var contents = f.read();
var base64font = Ti.Utils.base64encode(contents).toString();
doc.addFileToVFS("MarkaziText-Regular", base64font);
doc.addFont('MarkaziText-Regular', 'markazi-text', 'normal');
doc.setFontSize(20);
doc.setFont('markazi-text', 'normal');
doc.text('The quick brown fox jumps over the lazy dog', 20, 20);
var tempFile = Ti.Filesystem.getFile(Ti.Filesystem.getTempDirectory(), 'report.pdf');
if (tempFile.exists()) {
tempFile.deleteFile();
}
tempFile.write(doc.output());
I've also tried to write the file from a blob:
var reader = new FileReader();
reader.onloadend = function () {
tempFile.write(reader.result);
};
reader.readAsText(getBlob(buildDocument()));
But the pdf is empty if I use this. I've also tried the library in a webview within a titanium application, which does work but I don't really want to go that road. It would require too many changes to the code.
Expected:
Actual:
I've finally resolved it by creating a local HTML file. In this HTML file I've loaded jsPDF and my own JavaScript to generate a PDF file. I've loaded this HTML file in a WebView.
I'm generating all the data needed for the PDF in an Alloy controller. I'm sending this data to my WebView JavaScript by firing an app event and catching it in the WebView.
After the PDF is created I trigger an app event in the WebView that contains the base64 data of the jsPDF doc:
Ti.App.fireEvent('app:pdfdone', {
output: doc.output('dataurlstring').replace("data:application/pdf;filename=generated.pdf;base64,", "")
});
I finally save this as a file in the Alloy controller:
var f = Ti.Filesystem.getFile(Ti.Filesystem.getTempDirectory(), 'doc.pdf');
f.write(Ti.Utils.base64decode(e.output));

Creating PDF of a gdoc from a gsheet script

I have written a script within a gsheet that can create a gdoc based on the information in a row in the spreadsheet.
I am then trying to create a PDF of the gdoc that has been generated by the script in the gsheet. I am trying to make this all one seamless function where the gdoc is created with the pertinent information and then a pdf is automatically created as well. However, the PDF generated is always just a blank page.
I am able to add a script to a gdoc that will function correctly and create a pdf version of itself (or another gdoc), but when I run a function from a gsheet, it is always just the blank one-page pdf, Does anybody know why this is happening, or have a solution?
Here is an example of one of the simpler scripts I've tried and works in the gdoc script - obviously when running it from the gsheet I have to know the ID first and then open the gdoc from that.
function convertPDF(docId)
{
var doc = DocumentApp.getActiveDocument();
var docId = doc.getId();
var docFolder = DriveApp.getFileById(docId).getParents().next().getId();
var docblob = DocumentApp.getActiveDocument().getAs('application/pdf');
docblob.setName(doc.getName() + ".pdf");
var file = DriveApp.createFile(docblob);
var fileId = file.getId();
}
Thanks!
Chris

IE 9/10/11 not rendering images after some unknown threshold

I am building an app that pulls files from SharePoint 2013 or SharePoint 2010 for view in HTML. In C#, files are pulled out of SharePoint (multipage documents like Word, Excel, PDF, TIFF, etc), then are fed into various 3rd party software (DataLogics and Aspose) - which break the documents down into their individual pages, then streams the individual pages to the browser in PNG format.
So in HTML, we have an img element whose src is set to a specific URL in an ASHX service. The ASHX service grabs the file out of SharePoint and, based on query string params, returns the desired page as a Stream.
Here is how we shoot it back:
[WebService(Namespace = "url")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class FileTransfer : IHttpHandler, IReadOnlySessionState
{
public void ProcessRequest(HttpContext context)
var stream = GetStream(context.Request);
int chunkSize = 2097152; //2MB
byte[] chunk = new byte[chunkSize];
int bytesRead = 0;
do {
bytesRead = stream.Read(chunk, 0, chunkSize);
HttpContext.Current.Response.OutputStream.Write(chunk, 0, bytesRead);
}
while (bytesRead > 0);
}
This works perfectly 100% of the time in any browser when the file we are breaking down comes directly from SharePoint.
We also provide a feature where the user can upload a document. This is where the problem comes in. Uploaded documents are not saved in SharePoint. Instead their data is stored in SessionState until the user chooses to save. Files are uploaded to an ASMX service, then the browser requests their individual pages via the above ASHX.
Files are uploaded like this in an ASMX service:
[WebMethod(EnableSession = true)]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
Public object Upload()
{
var request = HttpContext.Current.Request;
if (request.Files.Count == 1)
{
var uniqueId = request["uniqueId"];
var file = request.Files[0];
using (var memoryStream = new MemoryStream())
{
file.InputStream.CopyTo(memoryStream);
docInfo = UploadItem(uniqueId, pageNum, memoryStream.ToArray());
}
}
}
UploadItem adds the uniqueId and byte[] to SessionState.
Files are sent from javascript like this (FileUpload being tied to the change event of an input of type=file):
this.FileUpload = function (files) {
var upload = new XMLHttpRequest();
upload.onreadystatechange = () => {
if (this._curUploadRequest.readyState == 4) {
// handle response
}
};
UpdateFormDigest((<any>window)._spPageContextInfo.webServerRelativeUrl,(<any>window)._spFormDigestRefreshInterval);
var data = new FormData();
data.append("uniqueId", uniqueId);
data.append("pageNum", pageNum);
data.append("data", files[0]);
upload.open('POST', "myurl");
upload.setRequestHeader("X-RequestDigest", $("#__REQUESTDIGEST").val());
upload.send(data);
};
Now we come to the actual bug.
Images are rendered using:
<img src="url to ASHX service" />
In FireFox and Chrome, page images from uploaded documents always show up just fine. But in IE (9, 10, or 11), it renders only the first portion of them, then shows broken image icons on the image placeholders. For these broken images, the NET tab of IE shows it received 0kb and the error event is hit. But if I put a breakpoint in the ASHX just before it returns the stream, it always has a size.
More interestingly, if you take the url that the src is pointed to, open a new window and paste it in, the image shows up just fine.
I even tried to load the images in javascript first like this:
var img = new Image();
img.onload = function(){
// use jquery to append image to page
};
img.src = "url to ASHX service";
In this scenario, Chrome and Firefox work fine as usual, but IE fails again. Except this way, the NET tab of IE shows it received the correct size kb in response. However, it still shows the broken image icon and won't render images to the screen after some unknown threshold. The first several images come back, but once one breaks, all of the rest break.
I also modified the ASHX service to return base64 data instead of a stream, then bound the base64 to the src. In the debugger you can see the base64 assigned to the src of the img elements that show the broken image icon. So the data is there for sure, but IE just isn't rendering it...
I tried to recreate this problem outside of our SharePoint environment in this fiddle using knockout JS. Basically, I grab a ton of big images and throw them on the screen with each button click. But it works just fine. It works perfectly if I use jQuery too.
http://jsfiddle.net/bsdez92f/
Not sure where to go from here.
Any ideas?
So it turns out that the image size was causing a problem. I scaled the images down to thumbnail size on the server side and returned that to the browser. All is working fine at this point.

Javascript dynamically show local file

I have a local text file which is kept changing by other programs. I want to write a html and javascript based web page to show the content of file dynamically. I have searched in google and found that most solutions require to get this text file via html element. I wonder if there is a way to get the file via a fixed path(lets say it is a string of the file directory) in javascript. I am using Javascript fileReader. Any help will be appreciated.
This is not possible using javascript running inside the browser. You will not be able to do anything outside the browser.
EDIT:
You could run a Node.js server though that runs on localhost and does your file operations you desire. You could build a API so your html page that you load in the browser calls your serverscript to do your file operations.
Do you understand what I mean?
How much information does the text file hold, Depending on your scenario it might be worth looking into javascript localstorage W3SCHOOLS local storage. Would that help your situation ?
What you can do is allow the user to choose the file of interest, using a file-input. Once done, the browser wil have access to the file, even though the JS wont have access to the file's full-path.
Once the user has chosen the file, you can reload it and refresh the view pretty-much as often as you please.
Here's a short demo, using a file input (<input type='file'/>) and an iframe. You can pick pretty much anything the browser will normally display, though there are limits on the size of the file that will work - due to the limit of the length of a URL - the file's data is turned into a data-url and that url is set as the source of the iframe.
As a demo, pick a file and then load it. Now, open the file in another program and change it. Finally, press the load button once again - the new content now fills the iframe. You can trigger the loading of the file by a timer or any other event in the page. As far as I'm aware, you cannot re-load it when it changes, since there's no notification from the OS - you have to use a button, timer, element event or whatever. Basically, you have to poll for changes.
<!DOCTYPE html>
<html>
<head>
<script>
function byId(e){return document.getElementById(e);}
window.addEventListener('load', onDocLoaded, false);
function onDocLoaded()
{
// uncomment this line for on-demand loading.
byId('loadBtn').addEventListener('click', onLoadBtnClick, false);
}
// fileVar is an object as returned by <input type='file'>
// tgtElem is an <iframe> or <img> element - can be on/off screen (doesn't need to be added to the DOM)
function loadFromFile(fileVar, tgtElem)
{
var fileReader = new FileReader();
fileReader.onload = onFileLoaded;
fileReader.readAsBinaryString(fileVar);
function onFileLoaded(fileLoadedEvent)
{
var result,data;
data = fileLoadedEvent.target.result;
result = "data:";
result += fileVar.type;
result += ";base64,";
result += btoa(data);
tgtElem.src = result;
}
}
function onLoadBtnClick(evt)
{
var fileInput = byId('mFileInput');
if (fileInput.files.length != 0)
{
var tgtElem = byId('tgt');
var curFile = fileInput.files[0];
loadFromFile(curFile, tgtElem);
}
}
</script>
<style>
</style>
</head>
<body>
<button id='loadBtn'>Load</button><input id='mFileInput' type='file'/><br>
<iframe id='tgt'></iframe>
</body>
</html>
you can use nodejs to watch for a filechange using watchfile module, if you just want to watch the filechange and its content. you can run following code using node, but it only consoles the file changed in your terminal.
var fs=require('fs');
fs.watchFile('message.text', function (curr, prev) { //listens to file change
fs.readFile('message.text', function(err,data){ //reads the file
console.log(data.toString()); //consoles the file content
});
});

Java Download file from url with download dialog

I want to download a file from a url which initially shows some html, then displays a download dialog after 2-3 seconds. Obviously if I do this:
try {
URL url = new URL("http://my.url");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestProperty("Connection", "Keep-Alive");
con.setRequestProperty("Content-Length",
Integer.toString(Integer.MAX_VALUE));
con.setReadTimeout(Integer.MAX_VALUE);
con.setConnectTimeout(Integer.MAX_VALUE);
con.connect();
bis = new BufferedInputStream(con.getInputStream(), 4096);
byteArray = IOUtils.toByteArray(bis);
FileUtils.writeByteArrayToFile(new File("myFile"), byteArray);
} catch (Exception e) {
}
I will save the displayed .html rather than the file that is displayed in the save dialog.
How should I change the code in order to do this?
I'm guessing the dialog just has some javascript which waits a couple seconds and requests the file download embedded in the dialog somewhere.
If this is the case, if you figure out what element the 'real download' is contained in, you can use JSoup, or any other html parser library to scrape the link out of the page.
You obviously only have to do that if the download link is generated dynamically.
After doing what rossa suggests, I'd suggest setting javascript breakpoints in the dialog window to figure out how exactly the real url is getting requested.
Are you sure the url is the exact location of the file you want to download? I mean, is there any redirect - you can check in your browser and use HTTP headers extension for instance to check what's going on behind the scene.

Categories