首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >合并pdfs的更好方法

合并pdfs的更好方法
EN

Code Review用户
提问于 2015-11-30 13:16:21
回答 1查看 3.9K关注 0票数 1

我正在尝试合并两个pdfs -一个来自剃刀视图,一个来自服务器上的文件。要从剃刀视图创建pdf,我使用了以下nuget包:MVCRazorToPDF

不幸的是,这不允许我将现有文件与pdf合并,所以我下载了项目,并将PdfActionResult更改为接受mergeFilename。

然后使用以下方法生成新的pdf:

代码语言:javascript
复制
public byte[] GeneratePdfOutput(ControllerContext context, object model = null, string viewName = null,
    Action<PdfWriter, Document> configureSettings = null, string filename = null)
{
    byte[] output;

    if (!string.IsNullOrEmpty(filename) && File.Exists(filename))
    {
        using (var copyDoc = new Document())
        {
            using (var copyStream = new MemoryStream())
            {
                copyDoc.Open();

                PdfCopy copy = new PdfCopy(copyDoc, copyStream);
                copy.CloseStream = false;
                copy.AddDocument(new PdfReader(GetBytes(context, model, viewName, configureSettings)));

                using (var reader = new PdfReader(filename))
                {
                    reader.ConsolidateNamedDestinations();

                    for (int i = 1; i <= reader.NumberOfPages; i++)
                    {
                        PdfImportedPage page = copy.GetImportedPage(reader, i);
                        copy.AddPage(page);
                    }
                }

                copy.Close();
                copyDoc.Close();
                output = copyStream.ToArray();
            }
        }
    }
    else
    {
        output = GetBytes(context, model, viewName, configureSettings);
    }

    return output;
}

private byte[] GetBytes(ControllerContext context, object model = null, string viewName = null, Action<PdfWriter, Document> configureSettings = null)
{
    if (viewName == null)
    {
        viewName = context.RouteData.GetRequiredString("action");
    }

    context.Controller.ViewData.Model = model;

    using (var document = new Document())
    {
        using (var workStream = new MemoryStream())
        {
            PdfWriter writer = PdfWriter.GetInstance(document, workStream);
            writer.CloseStream = false;

            if (configureSettings != null)
            {
                configureSettings(writer, document);
            }

            document.Open();

            using (var reader = new StringReader(RenderRazorView(context, viewName)))
            {
                XMLWorkerHelper.GetInstance().ParseXHtml(writer, document, reader);
                document.Close();
                return workStream.ToArray();
            }
        }
    }
}

我想知道是否有办法这样做,以便GetBytes成为第一个函数的一部分--即我打开一个新文档,然后添加剃刀,如果服务器上有一个文件,我将使用相同的内存流和文档(而不是创建新的文件),而不需要使用其他文件。

EN

回答 1

Code Review用户

回答已采纳

发布于 2015-11-30 13:31:32

如果将第一行改为

byte[]输出;

代码语言:javascript
复制
byte[] output = GetBytes(context, model, viewName, configureSettings);  

然后恢复if条件,您可以提前返回。

因此剩下的代码(如果文件名有效且文件存在)可能会变成

  • 通过堆叠使用,节省一些水平间距
  • 通过将byte[] output用于PdfReader ctor
  • 使用copyStream.GetBuffer(),而不是调用它的ToArray()方法,该方法用于创建额外的数组。

就像这样

代码语言:javascript
复制
public byte[] GeneratePdfOutput(ControllerContext context, object model = null, string viewName = null,
    Action<PdfWriter, Document> configureSettings = null, string filename = null)
{
    byte[] output = GetBytes(context, model, viewName, configureSettings);  

    if (string.IsNullOrEmpty(filename) || !File.Exists(filename))
    {
        return output;
    }

    using (var copyDoc = new Document())
    using (var copyStream = new MemoryStream())
    {
        copyDoc.Open();

        PdfCopy copy = new PdfCopy(copyDoc, copyStream);
        copy.CloseStream = false;
        copy.AddDocument(new PdfReader(output));

        using (var reader = new PdfReader(filename))
        {
            reader.ConsolidateNamedDestinations();

            for (int i = 1; i <= reader.NumberOfPages; i++)
            {
                PdfImportedPage page = copy.GetImportedPage(reader, i);
                copy.AddPage(page);
            }
        }

        copy.Close();
        copyDoc.Close();
        return copyStream.GetBuffer();
    }
}
票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/112326

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档