最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Styling List with React PDF - Stack Overflow

programmeradmin0浏览0评论

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
Add a ment  | 

1 Answer 1

Reset to default 8

I 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;
      }
    });
  };
发布评论

评论列表(0)

  1. 暂无评论