Mescla arquivos PDF - Merge PDF - Asp.Net MVC 4 com C#(CSharp)

Autor : Antonio Carlos Ferreira de Azevedo
Postado em : 17/05/2016


Mesclar arquivos PDF

Mescla diversos arquivos PDF em um só arquivo, os arquivos devem ser passados como parâmetro em em uma lista de array de bytes(List<byte[]>), o retorno será um um array de bytes(byte[]).

PdfMerger

Chamada da função PdfMerger.MergeFiles(lista de arquivos PDF)

Necessita da biblioteca iTextSharp, para instalar vá até o menu TOOLS > LIBRARY PACKAGE MANAGER > PACKAGE MANAGER CONSOLE e instale o pacote a seguir.

PM> Install-Package iTextSharp


Agora crie uma nova Classe na pasta Models de seu projeto com o nome de PdfMerger.cs copie e cole o codigo abaixo.

/* 
 * PdfMerger
 * 
 * Mescla arquivos PDF.
 * 
 * Visite nossa página http://www.codigoexpresso.com.br
 * 
 */
using System;
using System.Collections.Generic;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;

public static class PdfMerger
{
    /// <summary>
    /// Mescla Arquivos PDF.
    /// </summary>
    /// <param name="sourceFiles">Arquivos PDF a serem mesclados</param>
    /// <returns>Novo documento PDF em um array de byte</returns>
    public static byte[] MergeFiles(List<byte[]> sourceFiles)
    {
        Document document = new Document();
        using (MemoryStream ms = new MemoryStream())
        {
            PdfCopy copy = new PdfCopy(document, ms);
            document.Open();
            int documentPageCounter = 0;

            // Percorre todos os Documentos
            for (int fileCounter = 0; fileCounter < sourceFiles.Count; fileCounter++)
            {
                // Cria leitor de PDF
                PdfReader reader = new PdfReader(sourceFiles[fileCounter]);
                int numberOfPages = reader.NumberOfPages;

                // Percorre todas as páginas do Documento
                for (int currentPageIndex = 1; currentPageIndex <= numberOfPages; currentPageIndex++)
                {
                    documentPageCounter++;
                    PdfImportedPage importedPage = copy.GetImportedPage(reader, currentPageIndex);
                    PdfCopy.PageStamp pageStamp = copy.CreatePageStamp(importedPage);

                    pageStamp.AlterContents();

                    copy.AddPage(importedPage);
                }

                copy.FreeReader(reader);
                reader.Close();
            }

            document.Close();
            return ms.GetBuffer();
        }
    }
}


Para ficar mais claro vou postar aqui um trecho de código onde montamos um relatório em PDF devolvendo em byte[] e armazenamos em um List<byte[]> para impressão mesclada.

public ActionResult Fichas()
{
    // Instancia nossa lista de array de bytes
    List<byte[]> listaRelatorios = new List<byte[]>();

    // Adiciona as fichas das empresas de 1 a 4 em nossa lista
    listaRelatorios.Add(FichaEmpresa(1, "Ficha Empresa"));
    listaRelatorios.Add(FichaEmpresa(2, "Ficha Empresa"));
    listaRelatorios.Add(FichaEmpresa(3, "Ficha Empresa"));
    listaRelatorios.Add(FichaEmpresa(4, "Ficha Empresa"));

    // Gera em nosso navegador o relatório em formato PDF com todas as fichas de empresas informadas
    return File(PdfMerger.MergeFiles(listaRelatorios), "application/pdf");
           
}
public byte[] FichaEmpresa(int id, string DisplayName)
{
    // Instancia nosso relatório
    LocalReport lr = new LocalReport();
    string path = Path.Combine(Server.MapPath("~/Report"), "FichaEmpresa.rdlc");

    // Verifica se o Relatorio existe
    if (System.IO.File.Exists(path))
    {
        lr.ReportPath = path;
        lr.DisplayName = DisplayName;
    }
    else
    {
        // Se não existe retorna nulo 
        return null;
    }


    // Instancia a Classe para tratamento de dados de nossas empresas
    dalEmpresa dalempresa = new dalEmpresa();

    // Carrega os dados da empresa por seu id
    Empresa empresa = dalempresa.getEmpresaId(id);

    // Carrega o logo da empresa em nosso formulario
    // Estele logo foi gravado em nosso banco de dados utilizando a funcao para converter imagem para byte 
    ReportParameter Logo = new ReportParameter("Logo", Convert.ToBase64String(empresa.Logo));
    lr.SetParameters(new ReportParameter[] { Logo });

    lr.Refresh();

    // Carrega nossa classe empresa no dataset do relatorio
    ReportDataSource rd = new ReportDataSource("FichaEmpresa", empresa);
    lr.DataSources.Add(rd);


    string reportType = DisplayName;
    string mimeType;
    string encoding;
    string fileNameExtension;

    string deviceInfo =

    "<DeviceInfo>" +
    "  <OutputFormat>" + DisplayName + "</OutputFormat>" +
    "  <PageWidth>29.7cm</PageWidth>" +
    "  <PageHeight>21cm</PageHeight>" +
    "  <MarginTop>0.5cm</MarginTop>" +
    "  <MarginLeft>0.5cm</MarginLeft>" +
    "  <MarginRight>0.5cm</MarginRight>" +
    "  <MarginBottom>0.5cm</MarginBottom>" +
    "</DeviceInfo>";

    Warning[] warnings;
    string[] streams;
    byte[] renderedBytes;

    renderedBytes = lr.Render(
        reportType,
        deviceInfo,
        out mimeType,
        out encoding,
        out fileNameExtension,
        out streams,
        out warnings);              

    // Retorna nosso relatório em um array de bytes
    return renderedBytes;
}


Comentários