creating PDF black background instead of image via jsPDF in React js - reactjs

Hi I am creating pdf with image background via jsPDF library. File creating successfully but making background black instead of image my code is this.
const exportBrocharPDF = () => {
let element = (
<div style={{ textAlign: "left", width:"600px"}}>
<div style={{ backgroundImage: `url("https://mentorlogix.com/pricebuilder/pdfimages/4.png")`}}>
<p style={{fontSize: "10px", color:"#000"}}>
Your investment in the maintenance package is just , billed directly to your credit card.
</p>
</div>
</div>
)
const doc = new jsPDF("p", "pt", "a4");
doc.html(ReactDOMServer.renderToString(element), {
callback: function (doc) {
doc.save('Brochar.pdf');
}
});
};
Result is like this
I am trying a lot but not success please anyone can help to resolve my issue

Related

How can I access the "arrow" button click event on Material UI data grid?

In the documentation of Material UI Data Grid it has this code snippet (I've made a couple slight changes like importing DataGrid instead of DataGridPro, etc.):
import { DataGrid, useGridApiRef } from '#material-ui/data-grid';
import Alert from '#material-ui/lab/Alert';
export default function PageChange() {
const apiRef = useGridApiRef();
const [message, setMessage] = React.useState('');
const data = {'dummy-data-for-now': ''};
React.useEffect(() => {
/* ---- Theoretically I would replace columnResize with 'pageChange' ---- */
return apiRef.current.subscribeEvent('columnResize', (params) => {
setMessage(
`Column ${params.colDef.headerName} resized to ${params.computedWidth}px.`,
);
});
}, [apiRef]);
return (
<div style={{ width: '100%' }}>
<div style={{ height: 180, width: '100%' }}>
<DataGrid apiRef={apiRef} {...data} />
</div>
{message && (
<Alert severity="info" style={{ marginTop: 8 }}>
{message}
</Alert>
)}
</div>
);
}
I am implementing API pagination of 10 results at a time. I would like to be able to make a new API call for the next (or previous) 10 results when I click the arrow buttons.
The documentation refers to pageChange as an event option, but when I use the code snippet, I don't know how to utilize it. I would really appreciate any insight anyone might have on how to handle this situation.
This is a picture of the data grid button, for reference
#MaxAlex, thank you for the tip! This sent me on the right path and I finally got it working with server-side pagination. Resource
The key for me was to realize that on the onPageChange property within the DataGrid: onPageChange={(newPage) => handlePageChange(newPage)}, "newPage" was an object with the page number. I didn't need to specifically access the forward and backward arrows, but instead, just manage "newPage" in my handlePageChange function.

How to write Validations while uploading file in React

I am working with React, and I am trying to upload a file and that file type should be only png.
When I upload png file it is working fine. but I need to stop uploading other type files. for example if I need to upload png file means, it's needs to work properly. by mistake if I upload audio file means the file should not be uploaded. Please tell me how to write validations like this.
This is my code
This is App.js
import React, { useState } from "react";
import 'antd/dist/antd.css';
import './index.css';
import { Row, Col, Button, Modal, Upload, message } from 'antd';
import { VideoCameraOutlined, AudioOutlined } from '#ant-design/icons';
import "./App.css";
const App = () => {
const props = {
beforeUpload: file => {
const audioValidation = file.type === "image/png"
if (!audioValidation) {
message.error('You can only upload PNG file!');
}
}
}
const [visible, setVisible] = useState(false)
const showPopUp = () => {
setVisible(true)
}
return (
<div>
<Row>
<Col span={24}>
<Button onClick={() => showPopUp()} type="primary">Show PopUp</Button>
<Modal
visible={visible}
>
<Upload {...props}>
<div style={{ display: "flex" }}>
<div>
<VideoCameraOutlined style={{ fontSize: "25px", backgroundColor: "red", padding: "10px", borderRadius: "50%" }} />
<h6>Upload Video</h6>
</div>
<div style={{ marginLeft: "5px" }}>
<AudioOutlined style={{ fontSize: "25px", backgroundColor: "red", padding: "10px", borderRadius: "50%" }} />
<h6>Upload Png</h6>
</div>
</div>
</Upload>
</Modal>
</Col>
</Row>
</div>
)
}
export default App
If you have any questions please let me know, thank you.
In the Antd documentation they tell you that you can use the 'accept' property to select the formats to be chosen by the end user, that way you do not have to verify anything, since it will only allow you to select that type of files. Basically as a normal input.
Antd Documentation Here
From the MDN doc page on <input>:
The accept attribute value is a string that defines the file types the file input should accept. This string is a comma-separated list of unique file type specifiers. Because a given file type may be identified in more than one manner, it's useful to provide a thorough set of type specifiers when you need files of a given format.
We can specify that an input should only accept .png files with the following:
<input type="file" accept=".png">
However, it appears that you're using Ant Design, and it doesn't look like the <Upload> component actually has a built-in way to provide accepted file types to the <input> element. Maybe this is something you can work around with the above information.
Ok, I read the code on github and this is what you should do.
beforeUpload: file => {
const audioValidation = file.type === "image/png"
return new Promise((resolve, reject) => {
if (!audioValidation) {
reject(null) // the file is not ok then abort
message.error('You can only upload PNG file!');
}else resolve(file) // the file is ok, so you should proceed.
}
}

Export React Page to PDF

I'd like to be able to export React Page to PDF file(s). So far, I've tried jsPDF and html2canvas to capture the page as an image and save it as a pdf. Sample code:
const input = document.getElementById('exportToPDF')
window.scrollTo(0,0)
html2canvas(input)
.then((canvas) => {
document.body.appendChild(canvas)
const imgData = canvas.toDataURL('image/png')
const pdf = new jsPDF()
pdf.addImage(imgData, 'PNG', 0, 0)
pdf.save("test.pdf")
});
and 'exportToPDF' example:
<div id="exportToPDF">...</div>
I ran into problems with the canvas got cut off when the page content is too large/long. How can I get it to break into multiple pages when needed? It appears as it's limited to one page only.
What I have tried: set window width and height to html2canvas but it didn't help.
Update: I'm open to try other ways to export React page to PDF file(s) and not having to use html2canvas that are free.
Have you tried react-pdf or react-to-pdf these 2 might work for you if you aren't using next.js
I also faced same issue, now resolved by using #progress/kendo-react-pdf
visit https://www.telerik.com/kendo-react-ui/components/pdfprocessing/ for examples
sample code
import { PDFExport } from "#progress/kendo-react-pdf";
const ref: any = React.createRef();
...
<button onClick={() => {
if (ref.current) {
ref.current.save();
}
}}
>
Export PDF
</button>
<div id="container">
<PDFExport paperSize="A4" margin="0.5cm" ref={ref}>
<div id="htmldata" >sample data</div>
</PDFExport>
</div>
If you don't want to display contents of htmldata you can add below css
#container {
width: 0px;
height: 0px;
overflow: hidden;
}

http://localhost:3000/[object%20Object] not found 404

In my react app, this is an array of filenames I get from server side
const photos = ["01-1913.JPG", "01-1913.1.jpg", "01-1913.2.jpg"]
and here is how I use it with JSX
{
photos.map(entry => {
return (
<div key={entry}>
<PhotoItem key={entry} url={`${process.env.REACT_APP_NODE_SERVER}/${entry}`} />
</div>
)
})
}
const PhotoItem = (url) => {
return (
<img
src={url}
onError={this.addDefaultSrc}
alt="photoItem"
style={{
width: "500px",
height: "600px",
border: "1px solid #123C69",
}}
></img>
);
};
```
I can not figure out why I am not getting the photo (only the dummy photo from the onError event I've used) and if it has anything to do with the Object%object error. Any help would be appreciated.
As mentioned in the comments, the PhotoItem component should look like this:
// Note that here props are named "props" instead of "url"
const PhotoItem = (props) => {
return (
<img
src={props.url}
onError={this.addDefaultSrc}
alt="photoItem"
style={{
width: "500px",
height: "600px",
border: "1px solid #123C69",
}}
></img>
);
};
Note that the first argument that a react component receives is props. So even if you name it url, the value that you are looking for url lives in url.url.
I also recommend to deconstruct your props like this:
const PhotoItem = ({url}) => {
return (
<img
src={url}
...
></img>
);
};
I faced this error on the developer console on a Next.js project right after upgrading Next from v10 to v12.
Turns out using an image as <img src={require()}/> is not working anymore, and throws this error.
Instead to fix the issue, you need to use Next's (almost) drop in replacement of Image component as;
import Image from 'next/image'
...
<Image src={require()}/>
This will fix the issue, if your Next project is throwing this error.

react-dropzone child icon not changing on state change

I have a react project and I am using the react-dropzone component:
import Dropzone from 'react-dropzone';
I want to make it stateful and show different images and text based on the state. I defined my states as:
const status = {
ready: 'ready',
preview: 'preview',
error: 'error',
requested: 'requested',
success: 'success',
failed: 'failed',
};
The state can change based on user actions (so when they drag a file onto the dropzone I update status in state as follows:
onDrop(acceptedFiles, rejectedFiles) {
// do some stuff here...
this.setState({ status: status.preview });
}
My render method is a three step process:
1. the actual render methos
render() {
const config = {
iconFiletypes: ['.xlsx'],
showFiletypeIcon: true,
};
return (
<div style={{ marginBottom: '30px' }}>
<Dropzone
config={config}
onDrop={files => this.onDrop(files)}
//className="dropzone"
multiple={false}
>
{this.renderDropZoneContent()}
</Dropzone>
</div>
);
}
choose what to render based on state:
renderDropZoneContent() {
switch (this.state.status) {
case status.ready:
return this.renderReadyState();
case status.preview:
return this.renderPreviewState();
// and on down for each state / status + default case...
}
}
and finally the code to render each case as functions:
renderPreviewState() {
return (
<div style={{ marginTop: '35px', textAlign: 'center' }}>
<i className="far fa-file-excel" style={{ verticalAlign: 'middle', fontSize: '50px' }} />
{/* There is more jsx here but I removed it for clarity */}
</div>
);
}
renderReadyState() {
return (
<div style={{ marginTop:'35px', textAlign:'center'}>
<i className="fas fa-cloud-upload-alt" style={{ verticalAlign: 'middle', fontSize: '50px' }} />
</div>
);
}
Nothing too crazy. My problem is that as the state changes, the text updates but the icon does not. This is an interesting problem because the logic of the application works, but its the specific element that does not get updated. Even more interesting is that I tried wrapping the entire return in another div and got the error: Uncaught DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node. I'm banging my head against the wall. If anyone has come across this before and have any tips it is greatly appreciate!!
Probably a conflict with how Font Awesome and React handle rendering.
If you are using React we recommend the react-fontawesome package or Web Fonts with CSS.
https://fontawesome.com/how-to-use/on-the-web/using-with/react

Resources