简体   繁体   English

使用 React 下载 pdf / Node.js

[英]Downloading a pdf with React / Node.js

I have created a react front end and a node.js API for jobs.我为工作创建了一个反应前端和一个 node.js API。 The react front end displays jobs that I may be interested in and gives each job a button that says Download Cover Letter. React 前端显示我可能感兴趣的工作,并为每个工作提供一个按钮,上面写着下载求职信。 When clicked, this button sends an axios POST request to my node.js API that then takes the request body, and creates a personalized cover letter for me that I can use to apply to jobs.单击后,此按钮会向我的 node.js API 发送一个 axios POST 请求,然后获取请求正文,并为我创建一封个性化的求职信,我可以用它来申请工作。 My issue is that the node.js API seems to be doing it's job, however my react application does not download my cover letter to my local machine.我的问题是 node.js API 似乎在做它的工作,但是我的反应应用程序没有将我的求职信下载到我的本地机器。 I am a bit confused as to why it is not working, as I believe my response headers in my node API is correct.我有点困惑为什么它不起作用,因为我相信我的节点 API 中的响应标头是正确的。

Here is my react code:这是我的反应代码:

import React from 'react';
import axios from 'axios';

const Job = (props) => {

    const onClickHandler = async () => {
        try {
        const payload = JSON.stringify({"position": props.position,"company": props.company,"fileTitle": "Ryan_Test"});
        
        const config = {
          method: 'post',
        //   url: 'http://test-with-nedal.herokuapp.com/cover-letter',
        url: 'http://localhost:1234/cover-letter',
          headers: { 
            'Content-Type': 'application/json'
          },
          data : payload
        };
        
        const { data } = await axios(config)
        //console.log(data);
        } catch (err) {
            console.log(err);
        }
    }

    return (
        <div className="col-sm-4">
        <div className="card my-3">
        <div className="card-body">
            <h5 className="card-title">{props.position}</h5>
            <h6 className="card-subtitle mb-2 text-muted">{props.company}</h6>
            <p className="card-text">{props.description.substring(0, 100)}...</p>
            <a href="#" className="btn btn-primary">View Job</a>
        </div>
        <div className="d-flex justify-content-end">
            <button onClick={onClickHandler} className="btn btn-success">Download Cover Letter</button>
            <span>Found on <span style={{color: 'green', paddingRight: '10px'}}>{props.poster}</span></span>
        </div>
      </div>
      </div>
    )
}

export default Job;

Here is my API endpoint in Node:这是我在 Node 中的 API 端点:

const express = require('express');
const dotenv = require('dotenv');
const dateFormat = require('./utils/dateFormat');
const cors = require('cors');

const app = express();
dotenv.config();

app.use(cors());

app.use(express.json());

async function generatePdf(html) { 
    const puppeteer = require("puppeteer");
    const browser = await puppeteer.launch({
        args: ['--no-sandbox'],
        headless: true
    });

    const page = await browser.newPage();
    await page.goto(`data:text/html,${html}`, {
        waitUntil: 'networkidle0'
    });
    const options = {
        format: 'A4',
        margin: { top: "60px", bottom: "60px", left: "15px", right: "15px" },
        printBackground: true,
    }
    const pdf = await page.pdf(options);
    await browser.close();
    return pdf;
}

app.post('/cover-letter', async (req, res) => {
    console.log(req.body);
    const {position, company, fileTitle} = req.body;
    const date = dateFormat(new Date());

    const coverLetter = `Way too long to include in a code snippet, but pretend a cover letter HTML is here that uses ${position} and ${company}`;
    
    const pdfBuffer = await generatePdf(coverLetter);

    const fileName = `attachment; filename=\"${fileTitle}.pdf\"`;
    res.setHeader("Content-Type", "application/octet-stream");
    //res.setHeader("Content-Disposition","inline; filename=\"test_resume_company_name.pdf\"");
    res.setHeader('Content-Disposition', `attachment; filename=\"test.pdf\"`);
    res.status(200).send(pdfBuffer);
});

app.listen(process.env.PORT, () => {
    console.log(`Listening on port ${process.env.PORT}...`)
})

It seems that you are not using the returned data from your API. I think you should try to change your button to an anchor and add the download attribute like this:看来您没有使用 API 返回的数据。我认为您应该尝试将按钮更改为锚点并像这样添加下载属性:

<a href={file} className="btn btn-success" download="file_name">Download Cover Letter</a>

And generate your file on a useEffect as soon as the page loads to reference on your button.并在页面加载后立即在 useEffect 上生成您的文件以引用您的按钮。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM