I´m trying to generate a PDF on my application, using something like this, from documentation:
var doc = new jsPDF();
doc.html(document.body, {
callback: function (doc) {
doc.save();
}
});
But what I need is to get this generated file, as a base64 content, to send as an attachment on an email. Is there a way to get this directly on callback?
It's worth noting that the datauri option changes the document location, see the following snippet from jsPDF lib:
case 'datauri':
case 'dataurl':
return global.document.location.href = datauri;
This is fine unless you are trying to use an IFrame, as it would cause its body to be replaced by an embed tag displaying the pdf just generated.
Instead, the safest option is to use datauristring as this simply returns the pdf in a base64 string:
var pdf = new jsPDF('p', 'pt', 'a4');
var base = pdf.output('datauristring'); // base64 string
console.log("base64 is ", base);
Honestly, I don't know why anybody would want to use the datauri option instead of datauristring as latter's behaviour it's what most people expect anyway.
You can do like below.
var pdf = new jsPDF('p', 'pt', 'a4');
pdf.html(document.getElementById('doc'), {
callback: function (pdf) {
// example text
pdf.text(20, 20, 'Hello world!');
pdf.text(20, 30, 'This is client-side Javascript, pumping out a PDF.');
var base = pdf.output('datauri'); // directly to base664
console.log("base64 is ");
console.log(base);
// you can generate in another format also like blob
var out = pdf.output('blob');
var reader = new FileReader();
reader.readAsDataURL(out);
reader.onloadend = function() { // for blob to base64
base64data = reader.result;
console.log("base64 data is ");
console.log(base64data );
}
pdf.save('DOC.pdf');
}
})
You can see more on output() method in the following link.
jspdf output() source code
Related
I am using Mvc.Net API with open XML. I need to replace multiple images in .docx file.I replace the images in current scenario but I don't get any Id or Name of the Image at my code side so facing difficulties to replace those images.
Here is my code
List<ImagePart> imgPartList = doc.MainDocumentPart.ImageParts.ToList();
foreach(ImagePart imgPart in imgPartList)
{
string Id=doc.MainDocumentPart.GetIdOfPart(imgPart);
byte[] imageBytes = File.ReadAllBytes(ImagePath);
BinaryWriter writer = new BinaryWriter(imgPart.GetStream());
writer.Write(imageBytes);
writer.Close();
}
Can I get the name of Image in ImagePart?
I would do something like this:
List<ImagePart> imgPartList = doc.MainDocumentPart.ImageParts.ToList();
foreach(ImagePart imgPart in imgPartList)
{
var imageId = document.MainDocumentPart.GetIdOfPart(imgPart.Id);
byte[] imageBytes = File.ReadAllBytes(ImagePath);
BinaryWriter writer = new BinaryWriter(imgPart.GetStream());
writer.Write(imageBytes);
writer.Close();
}
Also
This answer could help you
I'm trying to open a PDF file with print dialog in IE Edge, it works fine in chrome but not in IE
MVC code to return file using Evo Pdf tool:
var restClient = new RestClient(Request.Url.Scheme + "://" + Request.Url.Authority);
var restResponse = restClient.Execute(request);
if (restResponse.StatusCode == HttpStatusCode.OK)
{
htmlModel.HtmlString = restResponse.Content;
byte[] pdfBytes = PdfUtil.GetEvoPdfBytes(htmlModel);
if (pdfBytes != null)
{
return File(pdfBytes, System.Net.Mime.MediaTypeNames.Application.Pdf, htmlModel.PdfName + ".pdf");
}
}
Javascript code to open file with print dialog, below code works in chrome but not IE:
var req = new XMLHttpRequest();
req.open("POST", "/api/HtmlToPdf", true);
req.setRequestHeader("Content-Type", "application/json");
req.responseType = "blob";
req.onload = function (event) {
var blob = req.response;
console.log(blob.size);
var lin = window.URL.createObjectURL(blob);
// Works in chrome
var mywindow = window.open(lin, "_blank");
mywindow.focus();
mywindow.print();
};
req.send(JSON.stringify(
{
htmlModel: {
ElementSelector: "#div",
PageOrientation: "Portrait",
PdfName: "abc"
}
}));
IE11 does not support URL.createObjectURL(). So your code will not work for IE browser and you will not be able to open the blob with print dialog..
As a work around, you need to use msSaveBlob or msSaveOrOpenBlob for Internet Explorer browser.
These methods allow a user to save the file on the client as if the file had been downloaded from the Internet.
var blobObject = new Blob(["This is sample text..."]);
window.navigator.msSaveOrOpenBlob (blobObject, 'msSaveOrOpenBlob_testFile.txt');
References:
(1) Download a blob from HTTP URL in IE 11
(2) Saving files locally using Blob and msSaveBlob
(3) Blob download is not working in IE
We are implementing PDFJS to render pdf files on a website.
When trying to initiate a PDFdocument/Viewer as an arrayBuffer, we get al sorts of errors and the file is not rendered.
When opening the same file in the viewer from url (DEFAULT_URL variable), the file renders fine.
There are however some files that do render as streams. Comparing these files in notepad shows they have different encoding/characters.
This piece of code is used to open the file in the viewer:
function rawStringToBuffer( str ) {
var idx, len = str.length, arr = new Array( len );
for ( idx = 0 ; idx < len ; ++idx ) {
arr[ idx ] = str.charCodeAt(idx) & 0xFF;
}
return new Uint8Array( arr ).buffer;
}
function readSingleFile(e) {
var file = e.target.files[0];
if (!file) {
return;
}
var reader = new FileReader();
reader.onload = function(e) {
var contents = e.target.result;
var uint8array = rawStringToBuffer(contents);
pdfjsframe.contentWindow.PDFViewerApplication.open(uint8array,0);
};
reader.readAsText(file);
}
test.pdf helloworld pdf which is not rendered with code above.
test2.pdf helloworld pdf which does rendered with code above.
The behaviour is not browser dependent. The build is b15f335.
Is there something with the code or default configuration of the viewer so that test.pdf can not be rendered by the viewer?
I don't think that your string conversion routine rawStringToBuffer() does what you want. You are reading the file as text, which transforms UTF-8 to UTF-16. But rawStringToBuffer() just takes the low order byte of each UTF-16 character and discards the high order byte, which is not the inverse transform. This will work with 7-bit ASCII data, but not with other characters. The best way to convert a string to UTF-8 is with the TextEncoder API (not supported on all browsers but polyfills are available).
However, converting the data from UTF-8 and back again is unnecessary. Just use FileReader.readAsArrayBuffer() instead of readAsText() to produce your ArrayBuffer directly.
Here's an (untested) replacement function:
function readSingleFile(e) {
var file = e.target.files[0];
if (!file) {
return;
}
var reader = new FileReader();
reader.onload = function(e) {
var contents = e.target.result;
pdfjsframe.contentWindow.PDFViewerApplication.open(contents, 0);
};
reader.readAsArrayBuffer(file);
}
It's not going into the .then afterwards, and it's not throwing any error.
Here's my calling code:
function loadPage(base64Data, pageIndex) {
var pdfData = base64ToUint8Array(base64Data);
// this gets hit
PDFJS.getDocument(pdfData).then(function (pdf) {
// never gets here
pdf.getPage(pageIndex).then(function (page) {
var scale = 1;
var viewport = page.getViewport(scale);
var canvas = document.getElementById('pdfPage');
var context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
page.render({ canvasContext: context, viewport: viewport });
});
});
}
function base64ToUint8Array(base64) {
var raw = atob(base64); // convert base 64 string to raw string
var uint8Array = new Uint8Array(raw.length);
for (var i = 0; i < raw.length; i++) {
uint8Array[i] = raw.charCodeAt(i);
}
return uint8Array;
}
At one point it worked. When I step through it in the debugger, I can step into PDFJS.getDocument but that's way over my head.
My base64Data looks like JVBERi0x...g==. It's a base64 encoded pdf document.
To solve this, I had to add
PDFJS.disableWorker = true;
to the beginning of my loadPage function.
From View PDF files directly within browser using PDF.js,
PDF.js uses Web Workers concept of HTML5 internally to process the
request. If this statement is set to false, it creates an instance of
Web workers. Web Workers run in an isolated thread. For more
information on web workers; please refer
http://www.html5rocks.com/en/tutorials/workers/basics/
Promise is missing in your code. Here how i fixed this probelm:
PDFJS.getDocument(pdfData).promise.then(function (pdf) {
// do your stuff
});
I've been struggling to instantiate Blobs in dartlang as of late, but i worked out how to do it in version 8640
For those interested (I couldn't find an example anywhere on the net)
I did this:
HttpRequest req = new HttpRequest();
FileReader fileReader = new FileReader();
req.open("GET", "http://...", true);
req.responseType="blob";
req.overrideMimeType("image/png");
req.on.load.add( (event) {
if(req.readyState==4) {
Blob blob = req.response; // note NOT req.responseBlob
fileReader.on.load.add( (evt) {
document.query('#myimage').src=evt.target.result;
});
fileReader.readAsDataURL(blob);
}
});
req.send();
I hope this helps somebody :)
If anyone landed here trying to figure out how to call the Blob constructor like I did, you actually need to feed it a list of lists (i.e. a List<List<int>>).
So, if you have a list of integers:
var binary = [1, 2, 3];
You pass it to the Blob constructor thusly:
var blorp = new Blob([binary]);
Calling var blorp = new Blob(binary); will result in a confusing message, claiming that the constructor wants a String.
From the answer embedded in the question above:
HttpRequest req = new HttpRequest();
FileReader fileReader = new FileReader();
req.open("GET", "http://...", true);
req.responseType="blob";
req.overrideMimeType("image/png");
req.on.load.add( (event) {
if(req.readyState==4) {
Blob blob = req.response; // note NOT req.responseBlob
fileReader.on.load.add( (evt) {
document.query('#myimage').src=evt.target.result;
});
fileReader.readAsDataURL(blob);
}
});
req.send();