How to set download file name html2pdf.js on blob url - naming

I am using html2pdf.js
I should show preview before my customer will download files.
The way of 'dataurlnewwindow' can show preview, but download button is not working.
So i change bloburl output, and download button is working.
But when i clicked download, i wanna set the download filename.
As you can see below, i cant set the download file name.
Does anyone knows to handle it?
This is my html2pdf.js code i used.
const opt = { margin: 10, filename, html2canvas: { width: 800, useCORS: true } };
html2pdf().set(opt).from(html).output('bloburl').then(r => { window.open(r) })
Even you guys know to support preview and download with name, plz tell me. i need help

You should try setting the filename at <a> tag in download property.
html2pdf().from(html)
.set(opt)
.toPdf()
.get('pdf')
.then((pdf) => downloadPdf(pdf, options));
const downloadPdf = (pdf, opt) => {
let link = document.createElement('a');
link.target = '_blank';
link.href = pdf.output('bloburl');
link.download = 'myFileName.pdf';
link.click();
link.remove();
}
This will open PDF in a new tab page, because of target=_blank and download it right after the click() event on <a> tag element.

Related

Display PDF in Vaadin version 14+

What is the best way to display PDF file in Vaadin 14? i want to display a pdf file in a dialog, but i'm not sure how to render the pdf files. I saw some post about embedded pdf view,pdf browser and EmbeddedPdfDocument, but i can't tell if they are compatible with 14 or not.Is there a new method to do this?
There is a third party addon to render a PDF in Vaadin 14.
Your can find it here: https://vaadin.com/directory/component/pdf-browser/
That gives you the possibility to render a pdf with this code:
StreamResource streamResource = new StreamResource(
"report.pdf", () -> getClass().getResourceAsStream("/report.pdf")); // file in src/main/resources/
PdfBrowserViewer viewer = new PdfBrowserViewer(streamResource);
viewer.setHeight("100%");
layout.add(viewer);
Alternatively you can do it in same way as it was commonly done in previous Vaadin framework versions, embedding in IFrame (see Show PDF in a Vaadin View ), which could look something like this
StreamResource streamResource = new StreamResource(
getPresenter().createPdfStreamSource(), report.getName() + ".pdf");
StreamRegistration registration = VaadinSession.getCurrent().getResourceRegistry().registerResource(resource);
IFrame iframe = new IFrame(registration.getResourceUri().toString());
iframe.setHEight("100%");
layout.add(iframe);
To do it in Vaadin Flow (without an addon) and in a dialog as requested, I'd like to present the following code for your dialog which can be called like any other class. I had to tweak Jean-Christophe his answer a bit.
public class ManualDialog extends Dialog {
private IFrame iFrame;
private final String fileName = "fileNameAsFoundUnderYourResourceMap";
public ManualDialog() {
this.setHeight("calc(100vh - (2*var(--lumo-space-m)))");
this.setWidth("calc(100vw - (4*var(--lumo-space-m)))");
buildLayout();
}
private void buildLayout() {
// HEADER
HorizontalLayout header = new HorizontalLayout();
header.setMaxHeight("1em");
header.setAlignItems(FlexComponent.Alignment.CENTER);
header.setJustifyContentMode(FlexComponent.JustifyContentMode.BETWEEN);
header.getStyle().set("margin-top", "-1em");
Span caption = new Span(getTranslation("main.download.manual"));
caption.getStyle().set("color", "black");
caption.getStyle().set("font-weight", "bold");
Icon closeIcon = new Icon(VaadinIcon.CLOSE);
closeIcon.setColor(GENERIC_BUTTON_COLOR.getDescription());
Button closeButton = new Button();
closeButton.setIcon(closeIcon);
closeButton.getStyle().set("border", "none");
closeButton.getStyle().set("background", "transparent");
closeButton.addClickListener(click -> this.close());
header.add(caption, closeButton);
this.add(header);
// PDF-VIEW
iFrame = new IFrame();
iFrame.setSizeFull();
StreamResource resource = new StreamResource(fileName, () -> new BufferedInputStream(getClass().getClassLoader().getResourceAsStream(fileName)));
StreamRegistration registration = VaadinSession.getCurrent().getResourceRegistry().registerResource(resource);
iFrame.setSrc(registration.getResourceUri().toString());
this.add(iFrame);
this.open();
}
}

Convert HTML page to PDF with CSS3 Support

I'm working on a small project whereby I create multiple CVs (or resumes) via an interface I've built in Vue + Laravel, which I can then export to PDF.
I'm having issues though when I export the PDF. Laravel DOMPDF doesn't let me have CSS3 properties inside the PDF, for example flex, or CSS variables. I believe PDFs only support CSS 2.0, but I have seen multiple PDFs being exported that are an exact carbon-copy of the website. For example, resume.io - when you create a CV via their site, they can export it and make it look exactly like the website version.
My question is: does anyone know of a library that I could use that ties into Vue or Laravel that will produce a carbon-copy of the website template into a PDF?
I have tried a few JS libraries that take screenshots of certain elements on the page, then try and fit them together, but it just doesn't work. I basically need a specific element on the page to be selectable and then saved to a PDF. Please see my example below:
As you can see, the white area is the CV preview, so I need that whole section saved to a PDF, minus the right hand side menu and the top-bar. I'm planning on building some really cool templates, but if I can't use modern CSS practices then it's going to be quite hard to make them into a PDF.
At the moment, I've got two views, the CV preview which you can see above, then another view which re-uses partials that are inserted in the PDF template. Obviously though, reusing the partials which have modern CSS applied then makes the PDF break or look broken.
My stack:
Laravel
Vue.js
TailwindCSS
Laravel-DOMPDF
If anyone could advise on the best way to go about this, I'd really appreciate it.
TIA
Since you didn't mentioned the converted page is in Vue or Blade, I'll explain both way.
Here's the Library, which all you need is to design a Blade view, then do something like this
Route::get('/doc', function () {
//
$data = Marketers::all();
// LoadView with $data
$pdf = PDF::loadView('pdf',$data)->setPaper('A4');
// LoadView with Compact
$pdf = PDF::loadView('pdf',compact('data'))->setPaper('A4');
// Then Download it
return $pdf->download('pdf.pdf');
});
Now in Vue you need jsPDF and htmlToCanvas or htmlToIMage
i used HTMLtoImage because i had some character issues for persian language so I'll help you base on HtmlToImage Library.
<template>
// Part you want to Convert to pdf or ...
<div ref="contentz" id="jsPdf" >
// Contents
<div/>
</template>
downloadFull(t) {
let self = this
switch (t) {
case 1:
const doc = new jsPDF("l", "mm", "a4");
htmlToImage.toCanvas(document.getElementById('jsPdf'))
.then(function (canvas) {
var img = canvas.toDataURL("image/jpeg");
var width = doc.internal.pageSize.getWidth();
var height = doc.internal.pageSize.getHeight();
doc.addImage(img, 'JPEG', 0, 0, width, 0);
doc.save('app.pdf');
})
.catch(function (error) {
self.$notifications.failedNotificationOnGetData(self)
});
break;
case 2:
htmlToImage.toJpeg(document.getElementById('jsPdf'), { quality: 1 })
.then(function (dataUrl) {
var link = document.createElement('a');
link.download = 'kalabala.jpeg';
link.href = dataUrl;
link.click();
})
.catch(function (error) {
self.$notifications.failedNotificationOnGetData(self)
});
}
break;
default:
break;
}
}
So here's my function which downloadFull(t) t will be the file type, you might don't need it or you can improve it with simple if/else without switch, first you you will import libraries like :
import jsPDF from 'jspdf';
import htmlToImage from 'html-to-image';
Then set page dimensions for jsPDF, then simply use HtmlToImage to get Canvas then set width, height and image Canvas with variables then simply add image to doc and save it. my functions are same but in first switch case I'll get PDF, in second I'll get JPEG.
If you're trying to do the first way but get download link in Vue page you must do the controller just like i explained at above then in VUE when u do API call you should use BLOB to download the file. Here's the Example :
getPDF(type) {
axios({
url : '/api/api_name/exportPDF',
method: 'POST',
responseType: 'blob'
})
.then(res => {
const url = window.URL.createObjectURL(new Blob([res.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'pdf.pdf');
document.body.appendChild(link);
link.click();
})
},
Good Luck.

Kendo Grid excel Export not working on chrome for 27K records but works for FF

I am trying to export kendo grid. It has around more than 27K records. when i try to export i get "Failed Network error" error in chrome, but this works fine on FF. I also tried to create kendo.ooxml.Workbook and tried to save it by Kendo.saveAs() but it also gives me same error. So i had to switch to server side.
Is there a limitation on Kendo.saveAs() method for file size ? It is strange that this scenario works fine on FireFox.
I'm used such workaround (saveAs is the FileSaver.js)
if (window.JSZip && window.JSZip.support && window.JSZip.support.blob) {
oldGenerate = window.JSZip.prototype.generate;
oldJSZip = window.JSZip;
window.JSZip.prototype.generate = function (options) {
blobForSave = oldGenerate.call(JSZipInstance, _.extend(
{},
options,
{
type: 'blob',
mimeType: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
}
));
return '';
};
window.JSZip = function () {
JSZipInstance = new oldJSZip();
return JSZipInstance;
};
workbook.toDataURL();
window.JSZip = oldJSZip;
window.JSZip.prototype.generate = oldGenerate;
saveAs(blobForSave, fileName);
} else {
kendo.saveAs({
dataURI: workbook.toDataURL(),
fileName: fileName
});
}
I have just resolved my problem with Kendo Export To PDF not working with Chrome. Using Network Traffic in Developer Tools I saw that there was a 404 error - DejaVuSans.ttf font not found. This did not stop Internet Explorer working - but it was the show stopper with Chrome. I moved the DejaVuSans font from the font folder to the Content folder (in with the calling css file), and changed the css code to (no path required now):
#font-face {
font-family: "DejaVu Sans";
src: url("DejaVuSans.ttf") format("truetype");
}
Perhaps not ideal to have a font in the Content folder when there is a font folder in the root directory, but my app works now.

UWP/WinJS: show a html page in a pop-up window

I am working on a JavaScript based UWP app. Now I need to dynamically show a html page(with a url) in a pop-up window.
I did some search, there is a ContentDialog I can probably use:
var object = new WinJS.UI.ContentDialog(element, options);
but I cannot find any JavaScript sample code for it. I couldn't figure out what should I pass as "element" and how I put the html in ContentDialog.
Thanks in advance for any help.
The WinJS playground shows you how to use the ContentDialog: http://winjs.azurewebsites.net/#contentdialog
The element you pass is the Html element you want to initiate as the dialog.
<div id="myDialog">I am the going to be the dialog content.</div>
 
var element = document.getElementById('myDialog');
var options = {
title: 'Main instruction',
primaryCommandText: 'Ok',
secondaryCommandText: 'Cancel'
};
var dialog = new WinJS.UI.ContentDialog(element, options);
If you want to set the dialog content dynamically you can do so with
var webview = document.createElement('x-ms-webview');
webview.src = 'http://stackoverflow.com';
dialog.element.querySelector('.win-contentdialog-content').appendChild(webview);
dialog.show();

Open new window from quick launch in Sharepoint Online

<script type="text/javascript">
//add an entry to the _spBodyOnLoadFunctionNames array
//so that our function will run on the pageLoad event
_spBodyOnLoadFunctionNames.push("rewriteLinks");
function rewriteLinks() {
//create an array to store all the anchor elements in the page
var anchors = document.getElementsByTagName("a");
//loop through the array
for (var x=0; x<anchors.length; x++) {
//does this anchor element contain #openinnewwindow?
if (anchors[x].outerHTML.indexOf('#openinnewwindow')>0) {
//store the HTML for this anchor element
oldText = anchors[x].outerHTML;
//rewrite the URL to remove our test text and add a target instead
newText = oldText.replace(/#openinnewwindow/,'" target="_blank');
//write the HTML back to the browser
anchors[x].outerHTML = newText;
}
}
}
</script>
I have this code I put in the seattle.master file before Then in quick launch when I edit links I put #openinnewwindow after the website address. On "try link" this opens the website right. My problem is when I save it. And click the link it does not open in a new window. Any ideas why this might be happening?
I realized for this code to work that I needed Publishing enabled.

Resources