You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将React JSX原始HTML传递给Api2pdf REST API并优化代码

解决React JSX表格数据传递给Api2pdf的最佳方案

你当前的问题在于Api2pdf接收的是纯HTML字符串,内嵌脚本无法访问React状态,且Api2pdf的渲染环境可能限制脚本执行。以下是两种更简洁可靠的实现方式:


方案一:预渲染数组为HTML片段(适合简单场景)

直接在React环境中将数组映射为HTML字符串,再嵌入到总HTML模板中,无需依赖远程执行脚本:

const fetchReportPdf = async () => {
  // 预渲染rocktrip数组为<li>标签字符串
  const rockTripItems = report.rocktrip.map(item => `
    <li>${item.Number_Of_Trips} trips made for Rock Type ${item.RockType}</li>
  `).join('');

  await fetch("https://v2018.api2pdf.com/chrome/html", {
    method: "post",
    headers: {
      Accept: "application/json",
      "Content-Type": "application/json",
      Authorization: "*Auth key placed here*",
    },
    body: JSON.stringify({
      html: `
        <html style="color: green" lang="en">
        <head>
          <title>Daily Report for ${newDate}</title>
          <link
           href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"
            rel="stylesheet"
            integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
            crossorigin="anonymous"
          />
        </head>
        <body>
          <div class="DailyReportTable_Container">
            <table
              class="table table-bordered border-dark table-sm"
              style="width: 900px"
            >
              <tbody>
                <tr>
                  <th colspan="6" class="text-center">
                    CIVIL WORKS FOR CONSTRUCTION OF THWAKE DAM EMBARKMENT AND
                    ASSOCIATED WORKS
                  </th>
                </tr>
                <tr>
                  <th>INSPECTOR</th>
                  <td colspan="1">${report.User}</td>
                  <th>SECTION:</th>
                  <td colspan="4" style="padding-left: 10px">${report.Section}</td>
                </tr>
                <!-- 插入预渲染的数组HTML -->
                <tr>
                  <td colspan="6">
                    <ul id="rockTripUL">${rockTripItems}</ul>
                  </td>
                </tr>
              </tbody>
            </table>
          </div>
        </body>
      </html>
          `,
      fileName: `${newDate} ${report.Section} ${report.Shift}.pdf`,
      options: {
        textAlign: "left",
        height: "11in",
      },
    }),
  })
  .then((res) => res.json())
  .then((res) => {
    document.getElementById(
      "Download_Button"
    ).innerHTML = `<a class="Download_Button" href="${res.pdf}" >Download PDF</a>`;
  });
};

方案二:用ReactDOMServer渲染完整组件(适合复杂JSX)

如果你的报告是复杂的React组件,直接用ReactDOMServer.renderToString将组件转为HTML字符串,完全复用React的渲染逻辑,无需手动拼接HTML:

  1. 先导入ReactDOMServer:
import ReactDOMServer from 'react-dom/server';
  1. 定义你的报告组件:
const ReportComponent = ({ report, newDate }) => (
  <html style={{ color: 'green' }} lang="en">
    <head>
      <title>Daily Report for {newDate}</title>
      <link
        href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"
        rel="stylesheet"
        integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
        crossOrigin="anonymous"
      />
    </head>
    <body>
      <div className="DailyReportTable_Container">
        <table
          className="table table-bordered border-dark table-sm"
          style={{ width: '900px' }}
        >
          <tbody>
            <tr>
              <th colSpan="6" className="text-center">
                CIVIL WORKS FOR CONSTRUCTION OF THWAKE DAM EMBARKMENT AND
                ASSOCIATED WORKS
              </th>
            </tr>
            <tr>
              <th>INSPECTOR</th>
              <td colSpan="1">{report.User}</td>
              <th>SECTION:</th>
              <td colSpan="4" style={{ paddingLeft: '10px' }}>{report.Section}</td>
            </tr>
            {/* 直接在组件内渲染数组,和React正常写法一致 */}
            <tr>
              <td colSpan="6">
                <ul>
                  {report.rocktrip.map(item => (
                    <li key={item.RockType}>
                      {item.Number_Of_Trips} trips made for Rock Type {item.RockType}
                    </li>
                  ))}
                </ul>
              </td>
            </tr>
          </tbody>
        </table>
      </div>
    </body>
  </html>
);
  1. 修改fetch函数,将组件转为HTML字符串传入:
const fetchReportPdf = async () => {
  // 将React组件转为HTML字符串
  const reportHtml = ReactDOMServer.renderToString(
    <ReportComponent report={report} newDate={newDate} />
  );

  await fetch("https://v2018.api2pdf.com/chrome/html", {
    method: "post",
    headers: {
      Accept: "application/json",
      "Content-Type": "application/json",
      Authorization: "*Auth key placed here*",
    },
    body: JSON.stringify({
      html: reportHtml,
      fileName: `${newDate} ${report.Section} ${report.Shift}.pdf`,
      options: {
        textAlign: "left",
        height: "11in",
      },
    }),
  })
  .then((res) => res.json())
  .then((res) => {
    document.getElementById(
      "Download_Button"
    ).innerHTML = `<a class="Download_Button" href="${res.pdf}" >Download PDF</a>`;
  });
};

关键说明

  • 内嵌脚本失效的原因:Api2pdf的Chrome渲染服务可能禁用了内嵌脚本执行,且脚本运行在独立环境,无法访问你的React应用状态变量。
  • 两种方案的优势:预渲染HTML片段适合简单场景,代码改动小;ReactDOMServer方案适合复杂组件,完全复用React的状态管理和组件逻辑,维护成本更低。

内容的提问来源于stack exchange,提问作者Cosmas Ochieng

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 03:35:22