I'm making a Windows store app (in Javascript) that generates a PDF. I convert this to base64 and then save that to file (if I want). This works fine.
(the PDF is a one page document (~30kb) with text, vector graphics and a small image)
Now I would like to be able to print this pdf directly from the app without having to open it in a separate application. Of course I've been doing a lot of searching, but the information I've come accross never seems to work. It either is in the wrong language, doesn't do what I'm looking for or just doesn't work. Also the Microsoft documentation is pretty vague and lacks decent examples.
Anyway, from what I've understood you can actually render a pdf page to bitmap and then send that to the printer. I decided to give it a try, so what I'm trying to do first is to save the pdf as an image to file.
Now I've managed to create a pdfPage object, now I'm supposed to do this:
pdfPage.renderToStreamAsync(outputStream).done( /* Your success and error handlers */ );
The outputStream is supposed to be a IRandomAccessStream object, but I can't seem to instance one. It doesn't show in the Streams list and when I type it in manually it doesn't work... Using InMemoryRandomAccessStream instead seems to work though.
var outputStream = new Windows.Storage.Streams.IRandomAccessStream(); //this don't work?
Even if outputStream is good, how do I save it to file? I've saved IBuffer's to file before, can I convert it to an IBuffer somehow? I can't find any information on that.
Also I believe it should be possible to show the outputStream as an image in the app. I can only find C# examples of this. How does this work in JS/HTML?
Okay I figured out how to save it:
Windows.Storage.ApplicationData.current.temporaryFolder.getFileAsync("mydocument.pdf").then(function (file) {
var pdfDocument = Windows.Data.Pdf.PdfDocument;
pdfDocument.loadFromFileAsync(file).then(function (pdf) {
page1 = pdf.getPage(0);
var accessStream = new Windows.Storage.Streams.InMemoryRandomAccessStream();
page1.renderToStreamAsync(accessStream).done(function () {
Windows.Storage.ApplicationData.current.temporaryFolder.createFileAsync("page1image.png", Windows.Storage.CreationCollisionOption.replaceExisting).then(function (file) {
file.openAsync(Windows.Storage.FileAccessMode.readWrite).then(function (filestream) {
Windows.Storage.Streams.RandomAccessStream.copyAndCloseAsync(accessStream.getInputStreamAt(0), filestream.getOutputStreamAt(0)).then(function () { console.log('done') });
});
});
});
});
});
Why do these seeminlgy straightforward things have to be so complicated?
The whole rasterization doesn't work too well. I mean to get a decent resolution (600dpi) the file takes some time to generate. I noticed that even the printer needs a couple of breaks while printing to keep up. This doesn't happen at all when I print the pdf directly. Also you lose the CMYK definition.
But what my real concern is: when I print an image it always adds 2cm margins to the page. The pdf image has margins of its own already so now it's double. 2cm is way too much anyway. I can't find any settings anywhere where I can change this.
So: does anyone know how to change the margins when printing from a Windows store app?
Related
I am working on a web-based project that is fully in Javascript. In it, I want users to be able to format their text exactly as they want. Naturally, I would like them to have the ability to upload their own fonts. However I'm not sure how to read the file they upload. I can take in the file, but I can't utilize their .ttf/.woff/woff2 etc. as an actual font file. I've used the FileReader API and have read in a ttf as a DataUrl, which puts it into base64. However I'm not sure how to turn it back into a file.
I've found this code from another post made on here, but it doesn't exactly do what I need it to do:
//read the file
const reader = new FileReader();
reader.addEventListener('load', (event) => {
<usersSelectedFile>.src = event.target.result;
});
var fontFile = reader.readAsDataURL(file);
With this, I get the file in base64. I know how to use font-face, but I've tried passing this fontFile in a font face style sheet but I got nothing from it.
My ultimate question is: How can I read a file in base64 as if it were a normal file? How should I reference it in font-face?
ALSO: I want to mention that I am trying to have this be stored in localStorage, as I wouldn't want any user-made changes to be global.
This is an interesting problem that I would like to know the definitive solution to. The best I could find by searching around was this solution, that utilizes and API for this specific problem. I have not tested it as of this moment, but it seems reliable.
As for the localStorage issue, have you tried converting the file to a JSON string using JSON.stringify(), and then using localStorage.setItem('name',DATAHERE)? I am not sure if this works with files, but this is what I use for arrays and non-string information when saving to localStorage.
Sorry for not having anything concrete for you. I'm looking forward to working this out further if none of my recommendations helped you.
I have a working Gulp script that I use to create my SVG sprites along with a preview page. But now I want to enrich the preview page, more precisely each icon in it, with information that I have in a separate json file. But I don't have any idea how to do this.
It should look something like this:
function taskFactory(name, spriteMode) {
return gulp.src(srcSvgDir + '*.svg')
.pipe(svgSprite(config))
.pipe(jeditor((json) => {
// read json file for this sprite
// iterate entries in json
// Find the location in preview page (by selector or placeholder string) and paste the information from the json entry.
}))
.pipe(gulp.dest(destDir));
}
But I have no idea if I even have access to this preview page that is being created. If anyone has a completely different idea, I'm open to anything.
In a case of emergency, I could write a C# console app that, after creating the sprite and preview page, parses and edits the latter file. I don't think that's so nice though, since I want to create it purely with Gulp.
I'm currently working on this game and I'm having trouble with image loading. Or should I say "dis-loading?"
I had this image file 'circle' and I used this image file to create sprite 'ball'. I deleted this file 'circle' and put new file and renamed it to 'circle'. Basically, I replaced it.
BUT, when I save my work and refresh my game, it still uses old file, although it's not in my asset folder anymore! When I change the file name to something else like 'circle1' then it suddenly works again(meaning new image is loaded). And then when I switch back to 'circle', it goes back to old image.
game.load.image('circle', 'assets/circle.gif');
P.S. I tried restarting my computer and my MAMP server.
This happens because the browser caches the assets. Basically put, the browser looks in the cache first, sees that a file with this name and this URL is already there and decides that it needs not to turn to the server and thus it shows you the old file. Clear the browser's cache and you should see the new file.
A workaround from Phaser's point of view would be to add simple versioning to the files, so instead of
game.load.image('circle', 'assets/circle.gif');,
you do the following:
var version = 1;
game.load.image('circle', 'assets/circle.gif' + '?' + version);
and change version's value every time you change an asset.
Took a while to figure out. (Still not sure)
I think if I create a new sprite with the image, it let the new image file to replace all the old ones. I don't know why. Please explain me if you know why or exact way of fixing this.
I've always been required show download size next to the file hyperlink. Only the file in question is rebuilt everyday and the file size can change often. So needless to say the size has been wrong for months. I'm not going to update our site daily to display needless info.
instead of
click here to download (20mb)
I'd prefer
click here to download [sizeof('file.xxx')]
The best solution would be javascript based or similar.
Since the file is on the server the solution would be best using ASP.NET. This blog post shows how to find the size of a file on the server. You may be able to adapt it to your needs.
javascript isn't really the best language to query the file system. There are ways to do it but they are all very hacky and you should stay away from them.
You can get the file size dynamically using server side code though :
long fileSize = (new FileInfo(# ".\file")).Length;
So in your markup, you could have something like :
<asp:Hyperlink runat="server" ID="hyperlinkFile" ...>
In your code behind, set it properly :
this.hyperlinkFile.Text = "Click here to download" + fileSize.ToString();
Use XMLHttpRequest to send a HEAD to the file and parse the HTTP Header that you get back, looking for the Content-Length field.
Something like:
var client = new XMLHttpRequest();
client.onreadystatechange = function() {
if(this.readyState == 2) {
alert(client.getResponseHeader("Content-Length"));
}
}
client.open("HEAD", address);
client.send();
More information here:
http://ajaxpatterns.org/XMLHttpRequest_Call
The final solution will be a mix between server code (asp.net) and client code (js).
You can build a REST service, that based on the file name or path, returns the size.
You can implement a js function that updates the inner text of every with the result of the REST service call.
Do something like this
click here to download (<%= C# or VB code for file size %>)
Inside the <%= %> tag you can put C# or VB code to find the file size. The server will evaluate it and then put the result where that tag is.
Just create a column name 'FileSize' in your database and fill it with asp.net after your upload has finished. This makes sure you won't overload your server too much.
[edit]Sorry didnt see your file size changes every day[/edit]
In that case you could write a little FileSystem Watcher and let it run in the background on your server or you could just get the filesize by checking the FileSystem info, way easier.
I thought about this more...I read all your answers, then clicked on some links to download various files from other websites. The browser tells me the size after I click 'download' in the dialog box.
I'm going to change the mind set that it is even necessary to include in the link.
Our site has so many pointless...('well other sites have this feature')...and the person I replaced didn't realize or care he that those other sites were built with a CMS that does all that automatically. Example: He was hard coding at the bottom of each page 'last updated: 01/01/1900' every time he saved the document.
edit:
I don't like the way I phrased this answer the other day. I realized that it is unnecessary to include the file size in the hyperlink, when all the major browsers will indicate the file size once you click 'download'. Like in my example above, there are so many instances I can find where the developer or webmaster before me added additional work for themselves by including "features" like filesizes/timestamps/etc... In my opinion adding features like that have/are:
No ROI
Likely to always be wrong
Required to have constant maintenance
Cheap way to make your site look "dynamic"
The last thing you do
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I want to convert HTML (containing JavaScript ) to a PDF. How can I do that?
I just want to show what is being shown in web page. I am displaying a gantt chart that is generated by a JavaScript library.
Now I want to save that HTML web page as a PDF, how to do that?
We are also looking for some way to convert html files with complex javascript to pdf.
The javasript in our files contains document.write and DOM manipulation.
We have tried using a combination of HtmlUnit to parse the files and Flying Saucer to render to pdf but the results are not satisfactory enough. It works, but in our case the pdf is not close enough to what the user wants.
If you want to try this out, here is a code snippet to convert a local html file to pdf.
URL url = new File("test.html").toURI().toURL();
WebClient webClient = new WebClient();
HtmlPage page = webClient.getPage(url);
OutputStream os = null;
try{
os = new FileOutputStream("test.pdf");
ITextRenderer renderer = new ITextRenderer();
renderer.setDocument(page,url.toString());
renderer.layout();
renderer.createPDF(os);
} finally{
if(os != null) os.close();
}
I'm surprised no one mentioned the possibility to use an API to do the work.
Granted, if you want to stay secure, converting HTML to PDF directly from within the browser using javascript is not a good idea.
But here's what you can do:
When your user hit the "Print" (for example) button, you:
Send a request to your server at a specific endpoint with details about what to convert (URL of the page for instance).
This endpoint will then send the data to convert to an API, and will receive the PDF in response
which it will return to your user.
For a user point of view, they will receive a PDF by clicking on a button.
There are many available API that does the job, some better than others (that's not why I'm here) and a Google search will give you a lot of answers.
Depending on what is written your backend, you might be interested in PDFShift (Truth: I work there).
They offer ready to work packages for PHP, Python and Node.js. All you have to do is install the package, create an account, indicate your API key and you are all set!
The advantage of the API is that they work well in all languages. All you have to do is a request (generally POST) containing the data you want to be converted and get a PDF back. And depending on your usage, it's generally free, except if you are a heavy user.
Using the browser's Print... menu item, you can utilize a PDF Printer Driver, like PDFCreator. This way any JavaScript included in the page is processed by the browser when the page is rendered.
PDFCreator is a free tool to create PDF files from nearly any Windows application.
Create PDFs from any program that is able to print
With Docmosis or JODReports you could feed your HTML and Javascript to the document render process which could produce PDF or doc or other formats. The conversion underneath is performed by OpenOffice so results will be dependent on the OpenOffice import filters. You can try manually by saving your web page to a file, then loading with OpenOffice - if that looks good enough, then these tools will be able to give you the same result as a PDF.
Check this out http://www.techumber.com/2015/04/html-to-pdf-conversion-using-javascript.html
Basically you need to use html2canvas and jspdf to make it work. First you will convert your dom to image and then you will use jspdf to create pdf with the images.
EDIT:
A short note on how it work.
We will use two libraries to make this job done. http://html2canvas.hertzen.com/ and
https://github.com/MrRio/jsPDF
First we will create a dom image by using html2canvas them we will use jspdf addImage method to add that image to pdf.
It seems simple but there are few bugs in jsPdf and html2cavas so you may need to change dom style temporarily.
Hope this helps.
Copy and paste this in your site to provide a link which will convert the page to a PDF page.
Convert To PDF
You can do it using a jquery,
Use this code to link the button...
$(document).ready(function() {
$("#button_id").click(function() {
window.print();
return false;
});
});
This link may be also helpful: jQuery Print HTML Pdf Page Options Link