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

React Native中ArrayBuffer创建Blob报错:HTML转PDF含签名导出求助

解决Expo React Native中Blob创建报错(ArrayBuffer不支持)的问题

问题原因

Expo环境下的Blob实现与Web端存在差异,原生不支持通过ArrayBuffer或ArrayBufferView创建Blob,这就是你在dataURItoBlob函数中触发Error: Creating blobs from 'ArrayBuffer' and 'ArrayBufferView' are not supported.的核心原因。

解决方案

以下是两种可行的修复方案,优先推荐方案2,更贴合Expo生态且兼容性更强:


方案1:修改dataURItoBlob函数,用fetch转换dataURI为Blob

利用fetch API处理data URI,生成Expo兼容的Blob对象:

async function dataURItoBlob(dataURI) {
  const response = await fetch(dataURI);
  return response.blob();
}

// 在handleSubmit中调用
async function handleSubmit() {
  const htmlContent = getHtmlWithSignature(); // 你的HTML获取逻辑
  const pdfDataURI = await htmlToPdf.convert(htmlContent); // 假设你使用的HTML转PDF库

  try {
    const blob = await dataURItoBlob(pdfDataURI);
    // 构建FormData上传Blob到后端
    const formData = new FormData();
    formData.append('pdf', blob, 'signed-document.pdf');
    
    await fetch('your-backend-api/upload-pdf', {
      method: 'POST',
      body: formData,
    });
  } catch (err) {
    console.error('处理PDF失败:', err);
  }
}

方案2:直接传递base64字符串给后端处理(推荐)

跳过前端生成Blob的步骤,将PDF的base64字符串传给ASP.NET Core后端,由后端负责生成文件并发送邮件,彻底规避Expo的Blob兼容问题:

前端代码(Expo)
import * as Print from 'expo-print';
import * as FileSystem from 'expo-file-system';

async function handleSubmit() {
  const htmlContent = getHtmlWithSignature();
  
  // 用Expo官方库生成标准尺寸PDF
  const { uri } = await Print.printToFileAsync({
    html: htmlContent,
    width: 612, // 72dpi下8.5英寸标准宽度
    height: 792, // 72dpi下11英寸标准高度
  });
  
  // 将PDF文件读取为base64字符串
  const pdfBase64 = await FileSystem.readAsStringAsync(uri, {
    encoding: FileSystem.EncodingType.Base64,
  });
  
  // 发送到后端API
  try {
    await fetch('your-backend-api/send-pdf-email', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        pdfBase64: pdfBase64,
        customerEmail: 'customer@example.com', // 替换为实际客户邮箱
        subject: '您的签名文档',
        body: '请查收附件中的签名文档'
      }),
    });
    alert('邮件已发送');
  } catch (err) {
    console.error('发送失败:', err);
    alert('发送失败,请重试');
  }
}
后端ASP.NET Core 8代码
using Microsoft.AspNetCore.Mvc;
using MimeKit;
using MailKit.Net.Smtp;

[ApiController]
[Route("api/[controller]")]
public class PdfEmailController : ControllerBase
{
    [HttpPost("send")]
    public async Task<IActionResult> SendPdfEmail([FromBody] PdfEmailRequest request)
    {
        if (string.IsNullOrEmpty(request.PdfBase64) || string.IsNullOrEmpty(request.CustomerEmail))
        {
            return BadRequest("缺少必要参数");
        }

        try
        {
            // 将base64转为字节数组
            byte[] pdfBytes = Convert.FromBase64String(request.PdfBase64);

            // 构建邮件内容
            var message = new MimeMessage();
            message.From.Add(new MailboxAddress("你的应用名称", "your-app-email@example.com"));
            message.To.Add(new MailboxAddress("客户", request.CustomerEmail));
            message.Subject = request.Subject ?? "您的签名文档";

            var bodyBuilder = new BodyBuilder();
            bodyBuilder.TextBody = request.Body ?? "请查收附件中的签名文档";
            // 添加PDF附件
            bodyBuilder.Attachments.Add("signed-document.pdf", pdfBytes, ContentType.Parse("application/pdf"));

            message.Body = bodyBuilder.ToMessageBody();

            // 发送邮件(替换为你的SMTP配置)
            using var client = new SmtpClient();
            await client.ConnectAsync("smtp.example.com", 587, MailKit.Security.SecureSocketOptions.StartTls);
            await client.AuthenticateAsync("smtp-username", "smtp-password");
            await client.SendAsync(message);
            await client.DisconnectAsync(true);

            return Ok(new { success = true, message = "邮件发送成功" });
        }
        catch (Exception ex)
        {
            return StatusCode(500, new { success = false, message = $"发送失败: {ex.Message}" });
        }
    }
}

// 请求模型
public class PdfEmailRequest
{
    public string PdfBase64 { get; set; }
    public string CustomerEmail { get; set; }
    public string Subject { get; set; }
    public string Body { get; set; }
}

依赖检查

如果使用方案2,确保package.json中包含以下Expo官方依赖:

{
  "dependencies": {
    "expo-print": "~12.8.1",
    "expo-file-system": "~16.0.8",
    // 其他项目依赖...
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 11:31:21