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

如何编程合并竖版与横版SSRS报表为单个可下载PDF?

实现SSRS纵向+横向报表合并为单一PDF的方案

嗨,这个需求完全可以搞定!你拆分出纵向、横向两个独立报表的思路是对的——毕竟SSRS单报表里确实没法直接混合不同页面方向,但我们可以通过编程手段把这两个报表生成的PDF合并成一个文件,给用户提供单一的下载入口。下面给你几种亲测有效的实现方案:

方案一:SSRS Web服务 + PDF合并库(最常用的编程方式)

这个方法的核心是先调用SSRS的官方Web服务,分别渲染两个报表为PDF字节流,再用PDF处理库把两个字节流合并成一个完整的PDF。推荐用C#结合iTextSharp(或iText 7)来实现,步骤如下:

  1. 引用必要的库:添加Microsoft.Reporting.WebForms(用于SSRS服务调用)和iTextSharp(用于PDF合并)的NuGet包。
  2. 编写报表渲染方法:调用SSRS的ReportExecutionService接口,获取两个报表的PDF字节数组。
  3. 合并PDF字节流:用iTextSharp读取两个PDF的页面,按顺序合并到一个新的PDF中,最后输出为下载文件。

这里给你一个简化的代码示例:

// 先封装一个渲染报表为PDF字节的辅助方法
private byte[] RenderSsrsReport(string reportPath, Dictionary<string, string> parameters = null)
{
    var rs = new ReportExecutionService();
    rs.Credentials = System.Net.CredentialCache.DefaultCredentials;
    rs.Url = "http://你的SSRS服务器地址/ReportServer/ReportExecution2005.asmx";

    var execHeader = new ExecutionHeader();
    rs.ExecutionHeaderValue = execHeader;
    var execInfo = rs.LoadReport(reportPath, null);

    // 设置报表参数(如果有的话)
    if (parameters != null && parameters.Count > 0)
    {
        var paramList = parameters.Select(p => new ParameterValue { Name = p.Key, Value = p.Value }).ToArray();
        rs.SetExecutionParameters(paramList, "zh-CN");
    }

    // 渲染为PDF格式
    string extension, encoding, mimeType;
    Warning[] warnings;
    string[] streamIds;
    return rs.Render("PDF", null, out extension, out encoding, out mimeType, out warnings, out streamIds);
}

// 合并两个PDF并输出下载
public void DownloadCombinedReport()
{
    // 获取纵向、横向报表的PDF字节
    var portraitPdf = RenderSsrsReport("/Reports/你的纵向报表");
    var landscapePdf = RenderSsrsReport("/Reports/你的横向报表");

    using (var combinedStream = new MemoryStream())
    {
        var document = new iTextSharp.text.Document();
        var pdfCopy = new PdfCopy(document, combinedStream);
        document.Open();

        // 添加纵向报表的所有页面
        var portraitReader = new PdfReader(portraitPdf);
        for (int i = 1; i <= portraitReader.NumberOfPages; i++)
        {
            pdfCopy.AddPage(pdfCopy.GetImportedPage(portraitReader, i));
        }
        portraitReader.Close();

        // 添加横向报表的所有页面
        var landscapeReader = new PdfReader(landscapePdf);
        for (int i = 1; i <= landscapeReader.NumberOfPages; i++)
        {
            pdfCopy.AddPage(pdfCopy.GetImportedPage(landscapeReader, i));
        }
        landscapeReader.Close();

        document.Close();

        // 输出给用户下载
        HttpContext.Current.Response.ContentType = "application/pdf";
        HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=Combined_Report.pdf");
        HttpContext.Current.Response.BinaryWrite(combinedStream.ToArray());
        HttpContext.Current.Response.End();
    }
}

方案二:子报表+分页控制(无需额外合并代码)

如果你不想单独生成两个报表,也可以做一个主报表,通过子报表嵌套的方式实现:

  • 主报表中先插入纵向子报表,设置子报表的页面方向为纵向,并且在子报表的最后一个控件后添加分页符。
  • 接着插入横向子报表,设置子报表的页面方向为横向,同时勾选“在新页上显示”选项。

不过这个方法有个小坑:SSRS的页面渲染有时候会忽略子报表的页面设置,导致横向页面还是纵向显示,所以需要在子报表的“页面设置”里单独指定纸张大小和方向,并且主报表的页面设置尽量和第一个子报表保持一致。如果遇到渲染异常,还是方案一更稳定。

方案三:命令行工具合并(适合自动化场景)

如果你的部署环境允许使用命令行工具,可以先通过SSRS的rs.exe工具生成两个独立的PDF文件,再用pdftk或Ghostscript这类命令行PDF工具合并:

  1. 用rs.exe生成纵向报表PDF:
    rs -i RenderReport.rss -s http://你的SSRS服务器地址/ReportServer -v ReportPath="/Reports/纵向报表" -v OutputFile="Portrait.pdf"
    
  2. 同理生成横向报表PDF,然后用pdftk合并:
    pdftk Portrait.pdf Landscape.pdf cat output CombinedReport.pdf
    

注意事项

  • 确保两个报表使用相同的参数,避免数据不一致。
  • 如果使用iTextSharp,注意版本兼容性:iText 7采用AGPL协议,商用场景需要确认版权;如果是旧项目,iTextSharp 5.x是MIT协议,更灵活。
  • 合并PDF时要注意页面顺序,确保纵向页面在前,横向页面在后。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:37:56