[英]How to implement react-pdf with print function
我想使用react-pdf來顯示PDF並開發用於直接打印的打印功能(例如使用window.print());
REST服務器是使用Jersey開發的。
PDF將從服務器生成,並使用返回類型為application / pdf的Jersey返回到React客戶端。 React客戶端將使用react-pdf顯示PDF。
我不想在“文件”中聲明URL路徑,因為如果React狀態更改並觸發了重新渲染,這將再次從服務器檢索PDF。 另外,我需要開發一種打印功能來打印顯示的PDF(因為如果再次從服務器檢索PDF,則PDF內容可能會更改)
下面顯示我的代碼:
服務器:
@Override
@GET
@Path("/pdf")
@Produces(MediaType.APPLICATION_PDF_VALUE)
public Response testPdf() throws Exception {
File file = new File("C:\\Desktop\\test.pdf");
FileInputStream fileInputStream = new FileInputStream(file);
ResponseBuilder response = Response.ok((Object) fileInputStream);
response.type("application/pdf");
response.header("Content-Disposition", "filename=test.pdf");
return response.build();
}
客戶
import React, { Component } from 'react';
import { Document, Page } from 'react-pdf';
import axios from 'axios';
class MyApp extends Component {
state = {
numPages: null,
pageNumber: 1,
pdfContent: null
}
componentDidMount(){
var that = this;
axio.get("url\Pdf).then((response) => {
that.setState({pdfContent:response.data});
}).catch((error) => {
console.warn(error);
});
}
onDocumentLoadSuccess = ({ numPages }) => {
this.setState({ numPages });
}
printHandler(){
window.print();
}
render() {
const { pageNumber, numPages } = this.state;
return (
<div>
<Document
file={this.state.pdfContent}
onLoadSuccess={this.onDocumentLoadSuccess}
>
<Page pageNumber={pageNumber} />
</Document>
<p>Page {pageNumber} of {numPages}</p>
<button onClick={() => this.setState(prevState => ({
pageNumber: prevState.pageNumber + 1 }))}>Next page</button>
<button onClick={() => this.setState(prevState => ({
pageNumber: prevState.pageNumber - 1 }))}>Prev Page</button>
<button onClick={this.printHandler}/>
</div>
);
}}
我只想一次獲取PDF並使用react-pdf顯示PDF。 另外,我想打印顯示的PDF。
我嘗試按照此行將response.data轉換為base64,因為未成功:(這將丟失pdf內容) 在ReactJS中將PDF編碼為base64
像這樣的代碼:
componentDidMount(){
var that = this;
axio.get("url\Pdf).then((response) => {
let reader = new FileReader();
var file = new Blob([response.data], { type: 'application/pdf' });
reader.onloadend = () => {
that.setState({
base64Pdf:reader.result
});
}
reader.readAsDataURL(file);
}).catch((error) => {
console.warn(error);
});
}
有人可以給我一些建議嗎? 還是實現我的目標的更好方法?
謝謝
最近,我在pdf部分得到了一個類似的用例,我的請求是Post,但是您可以毫無問題地將其設為Get。 因此,發生了什么:
1)-我正在使用axios向后端發出請求:
2) - 的要求就是我送的對象,但你不會有這樣的,因為你可能會只發送ID,例如:axios.get(“here.is.your /端點/ ID”);
3)-我正在使用:保存文件以保存收到的文件。
代碼的其余部分應該是不言自明的,我還添加了一些注釋。
import {saveAs} from "file-saver";
...
axios.post('here.is.your/endpoint', qs.parse(request), {
headers: {
'Content-Type': 'application/json'
},
responseType: 'blob' // here I am forcing to receive data in a Blob Format
})
.then(response => {
if (response.data) {
//Create a Blob from the PDF Stream
const file = new Blob(
[response.data],
{type: 'application/pdf'});
const name = 'Report.pdf';
saveAs(file, name);
} else {
throw new Error("Error in data type received.");
}
})
.catch(error => {
this.setState({
modalMessage: "Here Add Custom Message"
});
});
我仍然無法從后端獲取錯誤消息,如果在此方面取得了一些進展,我會回發短信-現在,我將顯示一條自定義消息。
希望對您有所幫助!
祝您好運!
在從后端接收到錯誤消息時進行更新 :
當請求失敗時,我們會從后端收到一個包含錯誤消息的JSON對象。 問題是,當我們強制接收Blob格式的響應時:responseType:'blob'-不管請求是否失敗,我們都會收到一個Blob對象。 因此,我正在考慮在axios提供的功能中更改responseType:transformResponse,但是不幸的是,我們無法訪問“ responseType”對象,只能訪問標頭。 此處: https : //github.com/axios/axios/pull/1155尚存在一個關於將其相應地轉換為responseType的公開問題,但仍未解決。
因此,我解決此問題的方法是使用訪存而不是axios。 這是一個例子:
fetch('here.is.your/endpoint', {
method: 'POST', // specifying the method request
body: JSON.stringify(request), // specifying the body
headers: {
"Content-Type": "application/json"
}
}
).then((response) => {
if (response.ok) { // checks if the response is with status 200 (successful)
return response.blob().then(blob => {
const name = 'Report.pdf';
saveAs(blob, name);
});
} else {
return response.json().then((jsonError) => {
this.setState({
modalMessage: jsonError.message // access the error message returned from the back-end
});
});
}
}).catch(function (error) {
this.setState({
modalMessage: "Error in data type received." // general handler
});
});
我希望這有幫助!
我很高興我幫助了!
我還有一個更新來接收錯誤消息
僅當您接收到文本消息而非JSON時,此消息才有效
fetch('here.is.your/endpoint', {
method: 'POST', // specifying the method request
body: JSON.stringify(request), // specifying the body
headers: {
"Content-Type": "application/json"
}
}
).then((response) => {
if (response.ok) { // checks if the response is with status 200 (successful)
return response.blob().then(blob => {
const name = 'Report.pdf';
saveAs(blob, name);
});
} else {
return response.text().then(function (error) {
throw new Error(error); // we should throw an Error with the received error
}
);
}
}).catch(function (error) {
this.setState({
modalMessage: error.message // that way we access the error message
});
});
我們之所以使用response.text()。then(),是因為我們設法將其從Promise轉換為文本。 使用.then()非常重要,因為此時Promise已解決,並且我們收到Promise值。 然后,我們只是拋出一個錯誤,因為我們無權訪問狀態對象。
這就是您從響應中獲取文本的方式。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.