求助:使用react-simple-maps生成的地图无法通过@react-pdf/renderer导出PDF
解决方案:react-simple-maps 地图导出 PDF
react-simple-maps 基于 SVG 渲染地图,而 @react-pdf/renderer 对复杂 SVG 组件的支持有限,直接嵌套通常无法正确解析。以下是几种可行的实现方案:
方案一:将 SVG 转图片后用 @react-pdf/renderer 导出
先把地图转为图片格式,再嵌入 PDF 文档,是兼容性最好的方案。
步骤:
- 安装依赖:
npm install html2canvas
- 组件实现代码:
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」功能导出。
步骤:
- 添加打印专用 CSS:
@media print { /* 隐藏页面其他元素 */ body > :not(.map-container) { display: none; } /* 让地图占满打印页面 */ .map-container { position: absolute; top: 0; left: 0; width: 100vw; height: 100vh; margin: 0; } }
- 添加导出按钮:
<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
相关产品推荐
相关产品推荐

