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

如何在React.js中解析REST API响应并利用字节数据生成PDF

Extracting and Generating PDF from REST API Response in React.js

First, let’s break down what we’re working with: your API returns an XML response where the <PDFContent> tag holds a base64-encoded string of the PDF file. Here’s a step-by-step guide to extract this content and render/download the PDF in React:

Step 1: Parse the XML Response to Get Base64 Data

Since the response is in XML format, we’ll use the browser’s built-in DOMParser to extract the base64 string from the <PDFContent> tag.

const parseXmlResponse = (responseText) => {
  const parser = new DOMParser();
  const xmlDoc = parser.parseFromString(responseText, "application/xml");
  const pdfContentElement = xmlDoc.querySelector("PDFContent");
  return pdfContentElement ? pdfContentElement.textContent : null;
};

Step 2: Convert Base64 String to a Blob

Base64 is a text-based representation of binary data—we need to convert it to a Blob (binary large object) to treat it as a proper PDF file.

const base64ToBlob = (base64String) => {
  // Decode base64 to binary string
  const binaryString = atob(base64String);
  // Convert binary string to Uint8Array
  const uint8Array = new Uint8Array(binaryString.length);
  for (let i = 0; i < binaryString.length; i++) {
    uint8Array[i] = binaryString.charCodeAt(i);
  }
  // Return Blob with PDF MIME type
  return new Blob([uint8Array], { type: "application/pdf" });
};

Step 3: Render the PDF in React

You have two straightforward options to display the PDF in your component: using an <iframe> (simple) or the react-pdf library (for more control).

Option A: Using an Iframe (Quick & Simple)

This is the easiest way to render the PDF without extra dependencies:

import { useState, useEffect } from "react";

const PdfViewer = ({ apiResponse }) => {
  const [pdfUrl, setPdfUrl] = useState(null);

  useEffect(() => {
    if (!apiResponse) return;

    // Extract base64 from XML
    const base64Data = parseXmlResponse(apiResponse);
    if (!base64Data) return;

    // Convert to Blob and create object URL
    const pdfBlob = base64ToBlob(base64Data);
    const url = URL.createObjectURL(pdfBlob);
    setPdfUrl(url);

    // Cleanup: Revoke URL to free memory when component unmounts
    return () => {
      if (url) URL.revokeObjectURL(url);
    };
  }, [apiResponse]);

  if (!pdfUrl) return <div>Loading PDF...</div>;

  return (
    <iframe
      src={pdfUrl}
      title="PDF Viewer"
      style={{ width: "100%", height: "80vh", border: "none" }}
    />
  );
};

Option B: Using react-pdf (Customizable)

For features like pagination or custom styling, use the react-pdf library. First install it:

npm install @react-pdf/renderer

Then create a component to render the PDF:

import { useState, useEffect } from "react";
import { Document, Page, pdfjs } from "@react-pdf/renderer";

// Configure PDF.js worker (required for react-pdf)
pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.min.js`;

const PdfViewer = ({ apiResponse }) => {
  const [pdfDocument, setPdfDocument] = useState(null);
  const [numPages, setNumPages] = useState(0);

  useEffect(() => {
    if (!apiResponse) return;

    const base64Data = parseXmlResponse(apiResponse);
    if (!base64Data) return;

    // Convert base64 to ArrayBuffer for pdfjs
    const binaryString = atob(base64Data);
    const arrayBuffer = new ArrayBuffer(binaryString.length);
    const uint8Array = new Uint8Array(arrayBuffer);
    for (let i = 0; i < binaryString.length; i++) {
      uint8Array[i] = binaryString.charCodeAt(i);
    }

    // Load PDF document
    pdfjs.getDocument(arrayBuffer).promise.then((doc) => {
      setPdfDocument(doc);
      setNumPages(doc.numPages);
    });
  }, [apiResponse]);

  if (!pdfDocument) return <div>Loading PDF...</div>;

  return (
    <div style={{ width: "100%", maxWidth: "800px", margin: "0 auto" }}>
      {Array.from({ length: numPages }, (_, i) => i + 1).map((pageNumber) => (
        <Document key={pageNumber} file={pdfDocument}>
          <Page pageNumber={pageNumber} style={{ margin: "1rem 0" }} />
        </Document>
      ))}
    </div>
  );
};

Step 4: Add a Download Button

Let users download the PDF by creating a temporary download link from the Blob:

const PdfDownloadButton = ({ apiResponse }) => {
  const handleDownload = () => {
    if (!apiResponse) return;

    const base64Data = parseXmlResponse(apiResponse);
    if (!base64Data) return;

    const pdfBlob = base64ToBlob(base64Data);
    const url = URL.createObjectURL(pdfBlob);

    // Create anchor tag and trigger download
    const a = document.createElement("a");
    a.href = url;
    a.download = "my-document.pdf"; // Set your desired filename
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);

    // Cleanup object URL
    URL.revokeObjectURL(url);
  };

  return <button onClick={handleDownload} style={{ padding: "0.5rem 1rem" }}>Download PDF</button>;
};

Putting It All Together

Combine these components in your main app to fetch, render, and let users download the PDF:

const App = () => {
  const [apiResponse, setApiResponse] = useState(null);

  useEffect(() => {
    // Example fetch call to your API
    fetch("your-api-endpoint")
      .then((res) => res.text()) // Get response as text (since it's XML)
      .then((text) => setApiResponse(text))
      .catch((err) => console.error("Fetch error:", err));
  }, []);

  if (!apiResponse) return <div>Fetching data...</div>;

  return (
    <div style={{ padding: "2rem" }}>
      <h1>PDF Viewer & Download</h1>
      <PdfViewer apiResponse={apiResponse} />
      <div style={{ marginTop: "1rem" }}>
        <PdfDownloadButton apiResponse={apiResponse} />
      </div>
    </div>
  );
};

export default App;

Key Tips

  • Memory Cleanup: Always revoke object URLs with URL.revokeObjectURL() after use to avoid memory leaks.
  • Error Handling: Add checks for cases where XML parsing fails or the base64 string is invalid.
  • CORS: Ensure your API allows cross-origin requests if your React app is hosted on a different domain.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:17:45