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

如何在React Native Expo中转换PDF原始数据并实现下载预览

Expo中处理API返回PDF并预览的正确方案

问题根源

你之前的错误在于直接将PDF文本/Blob丢入Buffer转Base64,忽略了PDF的二进制特性——尤其是开头的非ASCII标识字符,容易导致编码错乱,生成空文件或损坏文件。

正确处理流程

1. 确保API请求的响应类型正确

请求API时,务必设置responseType为'blob'或'arraybuffer',避免默认的文本解析损坏二进制数据:

// 示例:fetch请求设置responseType
const response = await fetch('你的PDF接口地址', {
  method: 'GET',
  headers: { /* 你的请求头 */ },
  responseType: 'blob' // 关键:获取二进制Blob数据
});
const pdfBlob = await response.blob();

2. 用Expo File System保存文件

Expo官方的expo-file-system是处理文件读写的首选,无需 eject,兼容iOS/Android:

import * as FileSystem from 'expo-file-system';
const Buffer = require('buffer').Buffer;

// 保存PDF到本地
const savePDF = async (pdfData) => {
  let base64Str;
  // 处理Blob类型数据
  if (pdfData instanceof Blob) {
    base64Str = await new Promise(resolve => {
      const reader = new FileReader();
      reader.onloadend = () => resolve(reader.result.split(',')[1]);
      reader.readAsDataURL(pdfData);
    });
  } 
  // 处理文本格式的PDF源码(你当前拿到的类型)
  else if (typeof pdfData === 'string') {
    const encoder = new TextEncoder();
    const uint8Array = encoder.encode(pdfData);
    base64Str = Buffer.from(uint8Array).toString('base64');
  }

  // 定义本地保存路径
  const savePath = `${FileSystem.documentDirectory}preview.pdf`;
  // 写入文件
  await FileSystem.writeAsStringAsync(savePath, base64Str, {
    encoding: FileSystem.EncodingType.Base64
  });
  return savePath;
};

3. 预览PDF文件

有两种预览方式:

方式一:调用系统默认应用打开

直接用Expo File System的openAsync方法,唤起系统PDF阅读器:

const previewPDF = async (pdfPath) => {
  await FileSystem.openAsync(pdfPath);
};

方式二:APP内嵌入预览(用expo-pdf-viewer)

安装依赖:

npx expo install expo-pdf-viewer

使用组件预览:

import { PDFViewer } from 'expo-pdf-viewer';
import { useState, useEffect } from 'react';
import * as FileSystem from 'expo-file-system';

export default function PDFPreviewScreen({ pdfData }) {
  const [pdfPath, setPdfPath] = useState(null);

  useEffect(() => {
    const loadPDF = async () => {
      const path = await savePDF(pdfData);
      setPdfPath(path);
    };
    loadPDF();
  }, [pdfData]);

  if (!pdfPath) return <Text>加载中...</Text>;

  return (
    <PDFViewer
      style={{ flex: 1 }}
      source={{ uri: pdfPath }}
    />
  );
}

关键注意事项

  • 不要手动将PDF二进制数据转成普通字符串再编码,直接处理Blob/ArrayBuffer或用TextEncoder转Uint8Array后再转Base64。
  • 保存路径必须用FileSystem.documentDirectory,这是Expo授权的可读写目录,避免权限报错。
  • 如果API返回的是完整PDF文本(如你提供的%PDF-1.4开头内容),确保文本没有被API请求截断,否则会生成损坏的PDF。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 04:06:13