Я пытаюсь объединить два (или более) Crystal Reports в проект ASP. net MVC, и я загрузил пакет itext7 NuGet для этого. Я пытаюсь собрать простое доказательство концепции, в котором я объединяю PDF с самим собой одним способом:
var rpt1 = new CrystalDecisions.CrystalReports.Engine.ReportDocument();
var rpt2 = new CrystalDecisions.CrystalReports.Engine.ReportDocument();
rpt1.Load(Server.MapPath("~/Reports/MyReport.rpt");
rpt2.Load(Server.MapPath("~/Reports/MyReport.rpt");
DataTable table = GetDataMethod();
rpt1.SetDataSource(table);
rpt2.SetDataSource(table);
Stream stream = rpt.ExportToStream(ExportFormatType.PortableDocFormat);
var write = new PdfWriter(stream);
var doc = new PdfDocument(write);
var merger = new PdfMerger(doc);
var doc1 = new PdfDocument(new PdfReader(rpt1.ExportToStream(ExportFormatType.PortableDocFormat)));
var doc2 = new PdfDocument(new PdfReader(rpt2.ExportToStream(ExportFormatType.PortableDocFormat)));
merger.Merge(doc1, 1, doc1.GetNumberOfPages());
merger.Merge(doc2, 1, doc2.GetNumberOfPages());
doc.CopyPagesTo(1, doc2.GetNumberOfPages(), doc2);
stream.Flush();
stream.Position = 0;
return this.File(stream, "application/pdf", "DownloadName.pdf");
Вы можете видеть, что я как бы бросаю все в стену и видя, что прилипает, поскольку я использую и PdfMerger.Merger()
, и PdfDocument.CopyPagesTo()
, и я думаю, что одного из них должно быть достаточно, чтобы выполнить работу самостоятельно? (И, конечно, я запустил код, пробуя каждый из них как по отдельности, так и вместе.) Но когда я запускаю приведенный выше код, загружаемый PDF-файл не объединяется, то есть отчет появляется только один раз. (Если я запускаю его с двумя разными отчетами, появляется только первый отчет.)
Теперь я возвращаю поток, пока делаю все интересные вещи с PdfMerger
и PdfDocument
объекты, так что для меня имеет смысл, что поток будет неизменным. Но все примеры использования iText 7, которые я нашел, возвращают либо поток, либо байтовый массив (например, этот вопрос StackOverflow ), так что, похоже, именно так он и должен работать.
Любые изменения, внесенные в код, либо не влияют, либо выдают ошибку, либо приводят к тому, что загруженный файл не читается браузером (т.е. не распознается как PDF). Например, я попытался преобразовать поток в байтовый массив и вернуть:
using (var ms = new MemoryStream()) {
stream.CopyTo(ms);
byte[] bytes = ms.ToArray();
return new FileContentResult(bytes, "application/pdf");
}
, но браузер не смог открыть загрузку. То же самое произошло, когда я попытался закрыть PdfDocument
перед возвратом потока (пытаясь заставить его записать слияние в поток).