I'm new with react. I want to create a website that can generate pdf file to download. I use React with Vite and Tailwind. I found this in internet: https://react-pdf.org/advanced#on-the-fly-rendering.
I try it in my code but nothing shows up.
import {Document, Page, PDFDownloadLink, StyleSheet, Text, View} from "#react-pdf/renderer";
import React from "react";
// Create styles
const styles = StyleSheet.create({
page: {
flexDirection: "row",
backgroundColor: "#E4E4E4",
},
section: {
margin: 10,
padding: 10,
flexGrow: 1,
},
});
// Create Document Component
const MyDoc = () => (
<Document>
<Page size="A4" style={styles.page}>
<View style={styles.section}>
<Text>Section #1</Text>
</View>
<View style={styles.section}>
<Text>Section #2</Text>
</View>
</Page>
</Document>
);
const Dashboard = () => (
<div>
<PDFDownloadLink
className=" bg-slate-600"
document={<MyDoc />}
fileName="somename.pdf"
>
{({ blob, url, loading, error }) =>
<button className=" bg-slate-500">Loading document...</button>
) : (
<button className=" bg-slate-500">Download now!</button>
)
}
</PDFDownloadLink>
</div>
);
export default Dashboard;
And i call this from my App.jsx file
import Dashboard from "./Dashboard";
function App() {
return (
<div className=" bg-slate-500">
<Dashboard />
</div>
);
}
export default App;
This is how it's look when run
This is when i inspect
I run it from brave browser, but it still the same when i run it from google browser.
Anyone know why this is happen? Any help is appreciated
So after a lot of searching, i found that my problem is caused by vite. This post pretty much solve it
Related
i'm currently working on a project using stitches with cra but i've stuck to a problem with css props.
here's my code
Texts/index.tsx
import React from 'react';
import { TextStyle } from './textStyle';
const Texts = ({ text, css }: PropsType) => {
console.log(css);
return (
<>
<TextStyle css={{ ...css }} >
<>{text}</>
</TextStyle>
</>
);
};
export default Texts;
and this index.tsx is exported to another components
Container/index.tsx
import { styled, css } from '../../../stitches.config';
// atoms
import Texts from 'src/components/atoms/texts';
const PageContainer = () => {
return (
<Container>
<Contents >
<div>
<Texts
css={{ color: 'red' }}
/>
<Texts
css={{ paddingTop: '20px' }}
/>
</div>
</Contents>
</Container>
);
};
export default PageContainer;
as you can see with the above code, contains css as its child but css is never rendered at all
can anyone help me with this issue?
FYI, console.log(css); returned undefined to me.
Thank you in advance!
I want to generate a PDF document that is generated after user click "Create PDF document" for my current React page. The document I want to generate will have the following:
Some, but not all component in the current page
Selectable
Only download the document when clicking and nowhere else
I have spent 3 hours researching on this trivial task, but somehow all library I have looking up for only allow their pre-defined component, or not selectable, or both. I know that this task is very trivial, but how exactly I could do that?
The best way to do this is, having a separate component that only contains what data need to be downloaded. And you can pass all necessary data using props.
I recommend using this library React-PDF.
App.js
import { PDFDownloadLink } from '#react-pdf/renderer';
import Document from './Document.js'
export default function App() {
const data = {/* Pass your data here */}
return (
<div className="App">
<PDFDownloadLink document={<MyDocument data={data}/>} fileName="somename.pdf">
{({ blob, url, loading, error }) =>
loading ? 'Loading document...' : 'Download now!'
}
</PDFDownloadLink>
</div>
);
}
Document.js
import React from 'react';
import { Document, Page, Text, View, StyleSheet } from '#react-pdf/renderer';
// Create styles
const styles = StyleSheet.create({
page: {
flexDirection: 'row',
backgroundColor: '#E4E4E4'
},
section: {
margin: 10,
padding: 10,
flexGrow: 1
}
});
// Create Document Component
const MyDocument = ({ data }) => ( //
<Document>
<Page size="A4" style={styles.page}>
<View style={styles.section}>
<Text>{data.something}</Text>
</View>
<View style={styles.section}>
<Text>{data.something}</Text>
</View>
</Page>
</Document>
);
In the main component, you will have a Download now! button. Your PDF will only contain data that you pass through props
I am stuck at the expo page. When I load the landing page, I get an error. .. "Module not found. " quick google search said i need to remove package-lock.json and reinstall npm back gain. I tried that method and i still run into the same problem. What should I do?
Failed to compile C:/Users/Asus/instragram/App.js Module not found: Can't resolve './components/auth/Landing' in 'C:\Users\Asus\instragram'
Below is the code of the landing page:
import React from 'react'
import {Text, View , Button} from 'react-native'
export default function Landing;({navigation}) {
return (
<view style = {{flex: 1, justifyContent: 'center'}}>
<button>
title="Register"
onPress = {() => navigation.navigate("Registr")}
</button>
<button>
title="Login"
onPress = {() => navigation.navigate("Login")}
</button>
</view>
)
}
Please try removing ; in line 3 of Landing page :
import React from 'react';
import {Text, View , Button} from 'react-native';
export default function Landing({navigation}) {
return (
<view style = {{flex: 1, justifyContent: 'center'}}>
<button>
title="Register"
onPress = {() => navigation.navigate("Registr")}
</button>
<button>
title="Login"
onPress = {() => navigation.navigate("Login")}
</button>
</view>
)
}
i create an app based on react-admin
and a fake server using json-server
my file structure is the following :
client ( here goes the react app )
node_modules
db.json
package-lock.json
pachake.json
range.js
then i created products and orders lists and show page :
the link for the show page of an order is ( for example order 3 ) :
http://localhost:3000/#/orders/3/show
and it shows the orders datils
what i wanna do is to download a pdf file contains this details , i tried the following code as a starting point :
import * as React from "react";
import {useQuery, Show, SimpleShowLayout, TextField } from 'react-admin';
import { PDFDownloadLink, Document, Page , View , Text } from '#react-pdf/renderer'
const MyDoc = ({}) => {
return (
<Document>
<Page size="A4">
<View>
<Text>
details must go here
</Text>
</View>
</Page>
</Document>
)};
const OrderShow = (props) => (
<Show {...props}>
<SimpleShowLayout>
<TextField source='order_number' />
<TextField source='reference_number' />
<TextField source='status' />
<TextField source='payment' />
<TextField source='shipment' />
<TextField source='created_at' />
<div>
<PDFDownloadLink document={<MyDoc /> } fileName="somename.pdf">
{({ loading }) => (loading ? 'Loading document...' : 'Download now!')}
</PDFDownloadLink>
</div>
</SimpleShowLayout>
</Show>
);
export default OrderShow
with this i got the following output :
when i click on Download now! a pdf with the content ' details must go here ' but instead of that i want the data about the current order
Try having a look at useShowController: https://marmelab.com/react-admin/Show.html#useshowcontroller
By using that, I think you will be able to access the data from the currently shown record, and build the PDF from there.
i did it this way and it works fine :
import React, {Component, PropTypes} from 'react';
// download html2canvas and jsPDF and save the files in app/ext, or somewhere else
// the built versions are directly consumable
// import {html2canvas, jsPDF} from 'app/ext';
export default class Export extends Component {
constructor(props) {
super(props);
}
printDocument() {
const input = document.getElementById('divToPrint');
html2canvas(input)
.then((canvas) => {
const imgData = canvas.toDataURL('image/png');
const pdf = new jsPDF();
pdf.addImage(imgData, 'JPEG', 0, 0);
// pdf.output('dataurlnewwindow');
pdf.save("download.pdf");
})
;
}
render() {
return (<div>
<div className="mb5">
<button onClick={this.printDocument}>Print</button>
</div>
<div id="divToPrint" className="mt4" {...css({
backgroundColor: '#f5f5f5',
width: '210mm',
minHeight: '297mm',
marginLeft: 'auto',
marginRight: 'auto'
})}>
<div>Note: Here the dimensions of div are same as A4</div>
<div>You Can add any component here</div>
</div>
</div>);
}
}
I'm facing a problem with the Android version.
I'm using gifted chat for my application chat. But the text input is covered by the keyboard so I can't see what I'm typing.
I'm using react-native version 0.51. I already followed couples of solutions but it still not working.
I tried this solution that uses keyboardAvoidingView and also added KeyboardSpacer and its also not working.
Any advice would be very great.
Here's my render component code
render() {
console.log(this.state);
return (
<View style={{flex: 1}}>
<GiftedChat
messages={this.state.messages}
onSend={Fire.shared.send}
loadEarlier={this.state.loadEarlier}
isLoadingEarlier={this.state.isLoadingEarlier}
user={{
name: this.props.profile.name,
_id: this.props.profile.user_id,
avatar: this.props.profile.profile_image
}}
renderUsernameOnMessage={true}
renderActions={this.renderCustomActions}
renderAvatar={this.renderAvatar}
renderBubble={this.renderBubble}
renderSend={this.renderSend}
renderSystemMessage={this.renderSystemMessage}
renderCustomView={this.renderCustomView}
renderFooter={this.renderFooter}
keyboardShouldPersistTaps={'always'}
/>
<KeyboardSpacer/>
</View>
)}
Looks like this is a common issue with React Native Gifted Chat and Expo on Android devices.
You could use the react-native-keyboard-spacer package to keep the content visible after opening the keyboard:
import React, { Component } from 'react';
import { View, Platform } from 'react-native';
import KeyboardSpacer from 'react-native-keyboard-spacer';
import { GiftedChat } from 'react-native-gifted-chat';
export default class Chat extends Component {
render() {
const giftedChatMessages = [
...
];
return (
<View style={{flex: 1}}>
<GiftedChat
messages={giftedChatMessages}
onSend={newMessages => onSend(newMessages[0].text)}
user={{
_id: 1,
}}
renderAvatar={() => null}
/>
{Platform.OS === 'android' ? <KeyboardSpacer /> : null }
</View>
)
}
}
I have also same issue. I solved it using adding android:windowSoftInputMode="adjustResize" in AndroidManifest.xml file as below :
<application
android:name=".MainApplication"
android:label="#string/app_name"
...
...
>
<activity
android:name=".MainActivity"
...
...
android:windowSoftInputMode="adjustResize" <!-- add here -->
>
...
</activity>
...
</application>
What about this:
import { KeyboardAvoidingView } from 'react-native';
<View style={{ flex: 1 }}>
<GiftedChat
messages={this.state.messages}
onSend={messages => this.onSend(messages)}
user={{
_id: 1,
}}
/>
{Platform.OS === 'android' && <KeyboardAvoidingView behavior="padding" />}
</View>;