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

求助:使用react-simple-maps生成的地图无法通过@react-pdf/renderer导出PDF

解决方案:react-simple-maps 地图导出 PDF

react-simple-maps 基于 SVG 渲染地图,而 @react-pdf/renderer 对复杂 SVG 组件的支持有限,直接嵌套通常无法正确解析。以下是几种可行的实现方案:

方案一:将 SVG 转图片后用 @react-pdf/renderer 导出

先把地图转为图片格式,再嵌入 PDF 文档,是兼容性最好的方案。

步骤:

  1. 安装依赖:
npm install html2canvas
  1. 组件实现代码:
import React, { useRef, useState } from "react";
import { ComposableMap, Geographies, Geography } from "react-simple-maps";
import { Document, Page, Image, PDFDownloadLink } from "@react-pdf/renderer";
import html2canvas from "html2canvas";

const MapToPDF = () => {
  const mapRef = useRef(null);
  const [mapImageData, setMapImageData] = useState(null);

  // 捕获地图转为图片
  const captureMap = async () => {
    try {
      const canvas = await html2canvas(mapRef.current, {
        allowTaint: true,
        useCORS: true // 处理跨域地理资源
      });
      const base64Image = canvas.toDataURL("image/png");
      setMapImageData(base64Image);
    } catch (err) {
      console.error("捕获地图失败:", err);
    }
  };

  // 定义 PDF 文档结构
  const MapPDFDocument = () => (
    <Document>
      <Page size="A4" style={{ padding: 0 }}>
        {mapImageData && <Image src={mapImageData} style={{ width: "100%", height: "100%" }} />}
      </Page>
    </Document>
  );

  return (
    <div>
      {/* 地图容器,添加 ref 用于捕获 */}
      <div ref={mapRef} style={{ width: 800, height: 600 }}>
        <ComposableMap projection="geoAlbersUsa">
          <Geographies geography="/usa.json">
            {({ geographies }) =>
              geographies.map((geo) => (
                <Geography key={geo.rsmKey} geography={geo} fill="#EAEAEC" stroke="#D6D6DA" />
              ))
            }
          </Geographies>
        </ComposableMap>
      </div>

      <button onClick={captureMap} style={{ margin: "1rem 0" }}>
        准备地图PDF
      </button>

      {/* 生成并下载 PDF */}
      {mapImageData && (
        <PDFDownloadLink document={<MapPDFDocument />} fileName="usa-map.pdf">
          {({ loading }) => loading ? "生成PDF中..." : "下载地图PDF"}
        </PDFDownloadLink>
      )}
    </div>
  );
};

export default MapToPDF;

注意事项:

  • 如果地理 JSON 资源来自跨域地址,需要确保服务器开启 CORS,或在 html2canvas 配置中启用 useCORS。
  • 可调整地图容器尺寸,确保导出的图片适配 PDF 页面比例。

方案二:利用浏览器打印功能直接导出 PDF

无需额外依赖,通过 CSS 打印媒体查询控制页面样式,直接用浏览器的「保存为 PDF」功能导出。

步骤:

  1. 添加打印专用 CSS:
@media print {
  /* 隐藏页面其他元素 */
  body > :not(.map-container) {
    display: none;
  }
  /* 让地图占满打印页面 */
  .map-container {
    position: absolute;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
    margin: 0;
  }
}
  1. 添加导出按钮:
<button onClick={() => window.print()}>导出地图为PDF</button>

优点:

  • 零额外依赖,实现简单;
  • 保留地图矢量清晰度(部分浏览器支持 SVG 打印)。

缺点:

  • 样式调试需要适配打印媒体规则;
  • 无法自定义 PDF 元数据(如标题、作者)。

方案三:手动用 @react-pdf/renderer 重构地图(适合简单场景)

如果需要纯矢量 PDF,可以手动解析地理数据,用 @react-pdf/renderer 的 Path 组件绘制路径。

示例代码片段:

import { Document, Page, Path, StyleSheet } from "@react-pdf/renderer";
import usaGeography from "./usa.json"; // 本地地理数据文件

const styles = StyleSheet.create({
  page: { width: "100%", height: "100%" },
  geography: { fill: "#EAEAEC", stroke: "#D6D6DA", strokeWidth: 0.5 }
});

const VectorMapPDF = () => (
  <Document>
    <Page size="A4" style={styles.page}>
      {usaGeography.features.map((feature) => (
        <Path
          key={feature.id}
          style={styles.geography}
          d={feature.geometry.coordinates}
        />
      ))}
    </Page>
  </Document>
);

注意事项:

  • 需要自行处理地理数据的坐标转换,适配 PDF 的画布坐标系;
  • 仅适合结构简单的地图,复杂地图(带标签、交互)工作量极大。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 05:43:26