Export React Big Scheduler view to PDF / CSV - reactjs

Has anyone succeeded in exporting the React Scheduler library view(day/week) into PDF or CSV?
Am working on a project that has ability to export to either PDF or CSV.
I have tried html2Canvas and pdfMake solution and the page seem blank.
Kindly help if you have.
Here is how i convert elements to canvas to generate pdf.
const handleExportToPDF = async () => {
html2canvas(document.querySelector('#printpdf'), {height: 1000, width: 800}).then(canvas => {
var data = canvas.toDataURL();
console.log(canvas)
var pdfExportSetting = {
content: [
{
image: await data,
width: 500
}
]
};
pdfMake.createPdf(pdfExportSetting).download("test_file.pdf");
});
};
Here is my scheduler
<span ref={scheduleRef} id='printpdf'>
<Scheduler
schedulerData={schedulerData}
prevClick={prevClick}
nextClick={nextClick}
onSelectDate={onSelectDate}
/>
</span>
Will appreciate.

Related

How to download the iframe as pdf document in react?I have tried using jspdf and kendo-react-pdf but getting blank document

import { PDFExport, savePDF } from '#progress/kendo-react-pdf';
const [contentRef, setContentRef] = useState('');
const downloadCertificate = () => {
const element: any =
document.querySelector('#certificate') || document.body;
savePDF(element, { paperSize: 'A4' });
};
const onClickDownload = () => {
downloadCertificate();
};
return (
<div>
<PDFExport ref={pdfExportComponent} paperSize="A4">
<iframe
id="certificate"
title="View your certificate"
className="u-els-margin-left-3x u-els-margin-right-3x"
width="776px"
height="600px"
srcDoc={contentRef}
/>
</PDFExport>
</div>
);
Using the above set of code to generate the pdf, I am importing the PDF Export and wrapping it around the block of code i want to export as pdf. Here the srcDoc of iframe is what I exactly want to export which assigned to a useState. So after the page renders the info is stored in srcDoc and I want to export this as pdf on click of the button which is part of the return.
currently iframes are not supported as part of the PDF export: https://www.telerik.com/kendo-react-ui/components/drawing/limitations-browser-support/#toc-elements-and-styles

AntD's Upload keeps showing failed tooltip but it is uploading successfully

I am using antd's Upload component, its task is to just upload the image and then I grab that image and send it to the API to store it. But I keep getting upload failed message tooltip as I am not using any action prop that they provide. Even their own website has this problem as I'm trying to upload something and it shows failed message but it has been actually uploaded. antd's Upload
I am using useState to save the file const [uploadedImage, setUploadedImage] = useState();
My fileProps looks like this:
const fileProps = {
name: 'file',
multiple: false,
onChange(info) {
if (info.file.status !== 'uploading') {
let reader = new FileReader();
reader.onload = (e) => {
setData({
...data,
image: new File([e.target.result], info.file.name),
});
setIsFileUploaded(true);
}
reader.readAsDataURL(info.file.originFileObj);
setUploadedImage(info.file.originFileObj);
}
},
};
I then pass it to the Upload Component:
<Upload {...fileProps}>
<Button icon={<UploadOutlined />}>Upload Image</Button>
</Upload>
Why does it keep showing Upload error Tooltip even though it is successfully uploading and I can store it? how can I remove this tooltip? I know there is a way to hide the list entirely by using: showUploadList: false but I want to show the uploaded file as sometimes during big uploads I don't have any sort of confirmation if the file is uploading or uploaded.
I have also created codesandbox for it: https://codesandbox.io/s/bold-bash-g3qkj
If you just want to save the file to the state, and not send it automatically to the server, you must set the property beforeUpload.
const fileProps = {
name: "file",
multiple: false,
beforeUpload: () => {
return false;
},
onChange(info) {
if (info.file.status !== "uploading") {
let reader = new FileReader();
reader.readAsDataURL(info.file);
setUploadedImage(info.file);
}
}
};

react-pdf: use PDFDownloadLink asynchronously without blocking the rest of the application

I'm using PDFDownloadLink from the react-pdf package to generate a PDF on the fly in my application and allow the user to download a report based on data being passed to the component that generates the PDF document. However, there are more than 400 pages that need to be rendered in this PDF, and this operation blocks the main thread for a few seconds. Is there any way to make this operation asynchronous, so the rest of the application will continue to function while the PDF is being generated? Also I would like to be able to cache the results, since the data being passed to the component can come from about 8 different arrays of data, which don't change very much, so switching between these arrays I would rather not to have to render the PDF all over again if the PDF for that given array has already been generated once before... I'm guessing the blob data needs to be stored somewhere, perhaps localStorage?
import { Page, Text, View, Document, StyleSheet, PDFDownloadLink } from '#react-pdf/renderer'
const App = () => {
const condition = "firstCondition";
const filteredRowData = rowData.filter(a => a.condition = condition);
return (
<PDFDownloadLink
document={<PDF_REPORT_Document rowData={filteredRowData} />}
fileName={"PDF_REPORT.pdf"}
style={{color:'white'}}
>{({ blob, url, loading, error }) =>
loading ? "Report loading..." : "Report ready to download"
}</PDFDownloadLink>
);
}
const PDF_REPORT_Document = (props) => {
const { rowData } = props;
const styles = StyleSheet.create({
page: {
flexDirection: 'column',
backgroundColor: '#E4E4E4'
},
section: {
margin: 10,
padding: 10,
flexGrow: 1
}
});
return(
<Document>
{rowData.map((row,index) =>
<Page size="A4" style={styles.page} key={index}>
<View style={styles.section}>
<Text>Name: {row.FULLNAME}</Text>
</View>
</Page>
)}
</Document>
);
}
I finally found the answer to this in an issue on github which addresses this exact problem:
Is your feature request related to a problem? Please describe.
It is an improvement. At the moment, if you use 'PDFDownloadLink' the PDF is being generated as the component loads.
Describe the solution you'd like
It is not mandatory, but having multiple heavy PDFs ready to be downloaded wouldn't be the best approach since not every user will need it.
Describe alternatives you've considered
I've used pdf() function to generate the blob and file-saver lib to download it:
import { saveAs } from 'file-saver';
import { pdf } from '#react-pdf/renderer';
import PdfDocument from '../PdfDocument';
const generatePdfDocument = async (documentData,fileName) => {
const blob = await pdf((
<PdfDocument
title='My PDF'
pdfDocumentData={documentData}
/>
)).toBlob();
saveAs(blob, fileName);
};
export default generatePdfDocument;

Problem when adding a picture from flamelink

I have a problem when I'm trying to load a picture from my Flamelink schema that is connected to my Firebase DB.
I have a simple component that displays a puppy for sale:
const PuppyCard = (props) => {
return (
<div className='PuppyCard'>
<div className='PuppyCard__img'>
<img src={props.data.picture} alt={props.data.name} />
</div>
<div className='PuppyCard__text'>
<h2>{props.data.name}</h2>
<h3>{props.data.sex}</h3>
<h4>{props.data.age}</h4>
<h4>{props.data.price}</h4>
</div>
</div>
)
}
And as you can see there is a props.data.picture as my src for the image, but when i try to load it on the website i get everything but the picture. After looking into my DB i saw that the picture is not a file but a reference to the other folder created by flamelink:
1
This is what i am fetching from the DB right now.
getPuppies = () => {
db
.collection('fl_content')
.get()
.then(docs => {
if (!docs.empty) {
let allPuppies = []
docs.forEach(function (doc) {
const puppy = {
id: doc,
...doc.data()
}
allPuppies.push(puppy)
})
this.setState({
puppies: allPuppies
}, () => {
this.setState({
isLoaded: true
})
})
}
})
}
Any help is appreciated!
I've managed to solve this problem, although now i realize that the question is not accurate.
What I was trying to do was to get the picture that was uploaded in the Flamelink CMS to display on the website, however i was only getting a file ID when i tapped into the property of the props.
My solution to this problem was:
store the fileID in a variable
Query the folder created by the flamelink CMS inside the Cloud Firestore called "fl_files" =>
db.collection('fl_files').doc(fileID).get().then(function (doc) {
var fileName = doc.Nf.nn.proto.mapValue.fields.file.stringValue;
console.log(fileName);
storageRef.child('flamelink/media/' + fileName).getDownloadURL().then(function (url) {
console.log(url);
var img = document.getElementById('an id for the image inside a react child component');
img.src = url
})
Please note that 'flamelink/media/' is inside the Storage, not inside Cloud Firestore.
Hope this helps somebody with the same problem I've had!
Issue closed :)

Html2canvas vs jspdf can't export svg in PDF file

I use html2canvas vs jsPDF in my Reactjs project and I had a required that's export a DOM node to PDF file. When I exported, HTML and CSS was keeped just SVG can't. I dont know why. Have another package on client can help me? Thank for your attetion.
Here is my code to export
const filename = 'TyVan.pdf';
html2canvas(document.querySelector('#buivanty'),{scale: quality}).then(canvas => {
let pdf = new jsPDF('l', 'mm', 'a4', true)
pdf.addImage(canvas.toDataURL('image/png', 1.0), 'png', 10, 10, 180, 150);
pdf.save(filename);
})
I was able to resolve it by doing post processing using onClone option
const options = {
scale: 1,
foreignObjectRendering: true,
onclone: (element) => {
const svgElements: any[] = element.body.getElementsByTagName('svg');
Array.from(svgElements).forEach((svgElement) => {
const bBox: any = svgElement.getBBox();
svgElement.setAttribute('width', bBox.width);
svgElement.setAttribute('height', bBox.height);
});
},
};
html2canvas(<HTMLScriptElement>document.querySelector('.main-container'), options).then(canvas => {
this.clipImage = canvas.toDataURL('image/png');
});

Resources