I have created a small React app to test out React PDF.
When the download link is clicked it creates the pdf as intended. My problem is that I have created a Display ponent which consists of an unordered list and three list items but it does not display the list correctly.
It renders from App.js as I would expect but when I print the PDF it mashes the list into a continuous line.
I tried different styles, placing in ponents and a bunch of other methods to no avail.
Is it possible to style like I wish using React PDF?
If so any suggestions would be very wele.
App.js
import './App.css';
import { MyDocument } from './pdf';
import { PDFDownloadLink } from '@react-pdf/renderer';
import { Display } from './display';
function App() {
return (
<div className="App">
{<PDFDownloadLink document={<MyDocument />} fileName="somename.pdf">
{({ blob, url, loading, error }) =>
loading ? 'Loading document...' : 'Download now!'
}
</PDFDownloadLink>}
<Display />
</div>
);
}
export default App;
Display.js
export function Display() {
return (
<ul>
<li>hihihihihihihi</li>
<br/>
<li>11111111111111</li>
<li>22222222222222</li>
</ul>
)
}
pdf.js
import React from 'react';
import { Page, Text, View, Document, StyleSheet } from '@react-pdf/renderer';
import {Display} from './display';
import './App.css';
// Create styles
const styles = StyleSheet.create({
page: {
flexDirection: 'column',
backgroundColor: '#E4E4E4'
},
section: {
margin: 10,
padding: 10,
flexGrow: 1
},
text: {
color: 'red',
display: 'flex',
flexDirection: 'column',
width: '100%'
}
});
// Create Document Component
export const MyDocument = () => (
<Document>
<Page size="A4" style={styles.page}>
<View style={styles.section}>
<Text>Section #1</Text>
<Text style={styles.text}><Display /></Text>
<Text>Lorem ipsum dolor sit amet consectetur adipisicing elit. Modi magnam unde excepturi labore id nam natus animi obcaecati eaque aspernatur, assumenda pariatur suscipit perferendis porro modi, earum ducimus? Odit, quo.</Text>
</View>
<View style={styles.section}>
<Text>Section #2</Text>
<Text>Lorem ipsum dolor sit amet consectetur adipisicing elit. Modi magnam unde excepturi labore id nam natus animi obcaecati eaque aspernatur, assumenda pariatur suscipit perferendis porro modi, earum ducimus? Odit, quo.</Text>
</View>
</Page>
</Document>
);
I have created a small React app to test out React PDF.
When the download link is clicked it creates the pdf as intended. My problem is that I have created a Display ponent which consists of an unordered list and three list items but it does not display the list correctly.
It renders from App.js as I would expect but when I print the PDF it mashes the list into a continuous line.
I tried different styles, placing in ponents and a bunch of other methods to no avail.
Is it possible to style like I wish using React PDF?
If so any suggestions would be very wele.
App.js
import './App.css';
import { MyDocument } from './pdf';
import { PDFDownloadLink } from '@react-pdf/renderer';
import { Display } from './display';
function App() {
return (
<div className="App">
{<PDFDownloadLink document={<MyDocument />} fileName="somename.pdf">
{({ blob, url, loading, error }) =>
loading ? 'Loading document...' : 'Download now!'
}
</PDFDownloadLink>}
<Display />
</div>
);
}
export default App;
Display.js
export function Display() {
return (
<ul>
<li>hihihihihihihi</li>
<br/>
<li>11111111111111</li>
<li>22222222222222</li>
</ul>
)
}
pdf.js
import React from 'react';
import { Page, Text, View, Document, StyleSheet } from '@react-pdf/renderer';
import {Display} from './display';
import './App.css';
// Create styles
const styles = StyleSheet.create({
page: {
flexDirection: 'column',
backgroundColor: '#E4E4E4'
},
section: {
margin: 10,
padding: 10,
flexGrow: 1
},
text: {
color: 'red',
display: 'flex',
flexDirection: 'column',
width: '100%'
}
});
// Create Document Component
export const MyDocument = () => (
<Document>
<Page size="A4" style={styles.page}>
<View style={styles.section}>
<Text>Section #1</Text>
<Text style={styles.text}><Display /></Text>
<Text>Lorem ipsum dolor sit amet consectetur adipisicing elit. Modi magnam unde excepturi labore id nam natus animi obcaecati eaque aspernatur, assumenda pariatur suscipit perferendis porro modi, earum ducimus? Odit, quo.</Text>
</View>
<View style={styles.section}>
<Text>Section #2</Text>
<Text>Lorem ipsum dolor sit amet consectetur adipisicing elit. Modi magnam unde excepturi labore id nam natus animi obcaecati eaque aspernatur, assumenda pariatur suscipit perferendis porro modi, earum ducimus? Odit, quo.</Text>
</View>
</Page>
</Document>
);
Share
Improve this question
edited Jun 4, 2021 at 1:54
Uken
asked Jun 2, 2021 at 7:56
UkenUken
1451 gold badge2 silver badges9 bronze badges
2
- 1 Did you find a solution for this? – Nikhil Gangai Commented Dec 27, 2021 at 12:04
- @NikhilGangai, unfortunately not. I ended up using react-to-print instead as it was better for my purposes in every way. – Uken Commented Jan 11, 2022 at 3:49
1 Answer
Reset to default 8I was able to figure this exact issue out, thanks to the help of a few folks from this discussion board: https://github./diegomura/react-pdf/issues/888#issuement-769040361
For your case, you would just need to modify your Display
ponent to look like this:
export function Display() {
return (
<View style={{flexDirection: "column", width: 400}}>
<View style={{ flexDirection: "row", marginBottom: 4 }}>
<Text style={{ marginHorizontal: 8 }}>•</Text>
<Text>hihihihihihihi</Text>
</View>
<View style={{ flexDirection: "row", marginBottom: 4 }}>
<Text style={{ marginHorizontal: 8 }}>•</Text>
<Text>11111111111111</Text>
</View>
<View style={{ flexDirection: "row", marginBottom: 4 }}>
<Text style={{ marginHorizontal: 8 }}>•</Text>
<Text>22222222222222</Text>
</View>
</View>
)
}
However, if you aren't manually creating the list and instead are just pasting it in from some dynamic data source... you will need to parse the html string so that each ul and li looks like the snippet above (<View style=, etc.).
I had to use this module for parsing my html: react-html-parser
And then parse my string like this:
const parseContent = (content) => {
const parsedHtml = ReactHtmlParser(content);
return parsedHtml.map((el) => {
const type = el?.type;
if (type === "ul") {
return el.props.children.map((kid, i) => {
return (
<View
style={{ flexDirection: "row", fontSize: regularSize, fontWeight: boldWeight, marginBottom: 4 }}
key={i}
>
<Text style={{ marginHorizontal: 8 }}>•</Text>
<Text>
{kid.props.children}
</Text>
</View>
);
});
} else {
return parsedHtml;
}
});
};