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

无需S3/Lambda:C#借助Amazon Textract提取多页PDF表格至Excel的难题

解决方案:C# .Net 借助Amazon Textract提取多页PDF表格到Excel(无S3/Lambda)

核心思路

处理多页PDF表格必须使用异步分析接口(StartDocumentAnalysis,而非文本检测的StartDocumentTextDetection),且完全可以无需依赖S3、SNS/SQS:直接传入PDF字节流发起异步任务,通过轮询获取分析结果即可。

步骤与代码实现

1. 安装依赖NuGet包

  • AWSSDK.Textract:AWS Textract官方SDK
  • EPPlus:用于生成Excel文件(可替换为其他Excel操作库)

2. 初始化Textract客户端

using Amazon.Textract;
using Amazon.Textract.Model;
using OfficeOpenXml;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

// 初始化客户端(建议通过环境变量/AWS CLI配置凭证,避免硬编码)
var textractClient = new AmazonTextractClient(RegionEndpoint.USWest2); // 替换为你的AWS区域

3. 提交异步表格分析请求

// 读取本地PDF文件为字节流
byte[] pdfBytes = File.ReadAllBytes(@"C:\your-path\multi-page-table.pdf");

var startRequest = new StartDocumentAnalysisRequest
{
    Document = new Document
    {
        Bytes = new MemoryStream(pdfBytes)
    },
    FeatureTypes = new List<string> { "TABLES" } // 指定仅提取表格
};

// 发起异步任务
var startResponse = await textractClient.StartDocumentAnalysisAsync(startRequest);
string jobId = startResponse.JobId;

4. 轮询任务结果

GetDocumentAnalysisResponse analysisResult = null;
bool isJobFinished = false;

// 轮询直到任务完成(建议间隔5-10秒,避免API限流)
while (!isJobFinished)
{
    var getRequest = new GetDocumentAnalysisRequest { JobId = jobId };
    analysisResult = await textractClient.GetDocumentAnalysisAsync(getRequest);

    switch (analysisResult.JobStatus)
    {
        case JobStatus.SUCCEEDED:
            isJobFinished = true;
            break;
        case JobStatus.FAILED:
            throw new System.Exception($"任务失败:{analysisResult.StatusMessage}");
        default:
            await Task.Delay(5000); // 等待5秒后再次查询
            break;
    }
}

5. 解析表格数据

// 建立块ID映射,方便快速查找子元素
var blockMap = analysisResult.Blocks.ToDictionary(b => b.Id, b => b);
var extractedTables = new List<List<List<string>>>();

// 遍历所有检测到的表格
foreach (var tableBlock in analysisResult.Blocks.Where(b => b.BlockType == BlockType.TABLE))
{
    var currentTable = new List<List<string>>();
    // 获取当前表格的所有单元格,按行、列排序
    var cells = analysisResult.Blocks
        .Where(b => b.BlockType == BlockType.CELL && b.ParentIds.Contains(tableBlock.Id))
        .OrderBy(b => b.RowIndex)
        .ThenBy(b => b.ColumnIndex);

    int currentRowNum = -1;
    List<string> currentRowCells = null;

    foreach (var cell in cells)
    {
        // 拼接单元格内的所有文本
        var cellText = string.Join(" ", 
            blockMap.Where(kv => cell.ChildIds.Contains(kv.Key) && kv.Value.BlockType == BlockType.WORD)
                    .Select(kv => kv.Value.Text));

        // 切换新行
        if (cell.RowIndex != currentRowNum)
        {
            if (currentRowNum != -1) currentTable.Add(currentRowCells);
            currentRowNum = cell.RowIndex;
            currentRowCells = new List<string>();
            // 填充空列(处理单元格不连续的情况)
            while (currentRowCells.Count < cell.ColumnIndex - 1)
            {
                currentRowCells.Add(string.Empty);
            }
        }
        else
        {
            // 填充同一行内的空列
            while (currentRowCells.Count < cell.ColumnIndex - 1)
            {
                currentRowCells.Add(string.Empty);
            }
        }
        currentRowCells.Add(cellText);
    }

    if (currentRowCells != null) currentTable.Add(currentRowCells);
    extractedTables.Add(currentTable);
}

6. 导出到Excel

// 配置EPPlus许可证(非商业用途可使用免费许可证)
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;

using (var excelPackage = new ExcelPackage())
{
    int sheetCount = 1;
    foreach (var table in extractedTables)
    {
        var worksheet = excelPackage.Workbook.Worksheets.Add($"表格{sheetCount++}");
        int row = 1;
        foreach (var rowCells in table)
        {
            int col = 1;
            foreach (var cellText in rowCells)
            {
                worksheet.Cells[row, col].Value = cellText;
                col++;
            }
            row++;
        }
    }

    // 保存Excel文件
    excelPackage.SaveAs(new FileInfo(@"C:\your-path\output-tables.xlsx"));
}

关键注意事项

  • 异步任务限制:单PDF最多支持1000页,文件大小不超过500MB
  • 凭证管理:优先使用AWS SDK默认凭证链(环境变量、~/.aws/credentials文件、IAM角色),禁止硬编码凭证
  • 错误处理:需捕获任务失败、API限流等异常,可添加重试逻辑
  • 轮询间隔:避免过于频繁查询,推荐5-10秒一次

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 13:37:58