如何使用内存流将多个 pdf 文件的 zip 存档发送到浏览器

问题描述 投票:0回答:1

我正在使用 MigraDoc 创建 pdf 和 ZipArchive 将其放入 zip 文件中并将其发送给客户端。如果只有一个 pdf,我设法让它工作,但当我尝试两个时,它会发送一个 1KB 文件,并显示它是空的。下图是有多个pdf时的情况

empty zip file

Migradoc 网站上几乎没有这方面的文档。如果我错过了,请告诉我。

这是我的代码:

控制器:

[HttpGet("FinalistDetailsReport")]
public IActionResult FinalistDetailsReport(string AuthToken, List<int> AppIdList)
{
    try
    {
        using (var stream = new MemoryStream())
        {
            using (var archive = new ZipArchive(stream, ZipArchiveMode.Create, true))
            {
                foreach (var appID in AppIdList)
                {
                    //create entry in zip folder
                    var file = archive.CreateEntry(appID.ToString() + ".pdf");

                    //get data
                    AppDetails data = App.getApplicationByAppID(appID);

                    //create pdf
                    MigraDocCore.DocumentObjectModel.Document pdf = buildPDF(data);

                    //render pdf
                    var pdfRenderer = new PdfDocumentRenderer();
                    pdfRenderer.Document = pdf;
                    pdfRenderer.RenderDocument();

                    using (var rendererStream = new MemoryStream())
                    using (var pdfStream = file.Open())
                    {                        
                        pdfRenderer.PdfDocument.Save(rendererStream, false);
                        rendererStream.CopyTo(pdfStream);
                    }
                }
            }
            return File(stream.ToArray(), "application/octet-stream", "Applications.zip");
        }
    }
    catch (Exception)
    {
        return BadRequest("Could not generate report");
    }
}

成分:

import { saveAs } from 'file-saver';

finalistDetails() {
    let wait = this.matDialog.open(WaitModalComponent);
    let appIdList: number[] = [13333];//, 13312]; I uncomment this when I test 2 files
    this.appSvc.FinalistDetailsReport(this.user.AuthToken, appIdList).pipe(takeUntilDestroyed(this.destroyRef)).subscribe(res => {
        wait.close();
        saveAs(res.body, 'Applications_' + DateTime.now().toFormat('MMM_d_y') + '.zip');
    }, error => {
        wait.close();
        this.splashSvc.SnackbarError(error.error, 10000);
    });
}

服务:

FinalistDetailsReport(authToken: string, applicationIdList: number[]): Observable<HttpResponse<Blob>> {
    let headers = new HttpHeaders({
        'Content-Type': 'application/json',
        'ApplicationName': 'Scholarships'
    });

    headers = headers.set('Accept', 'application/zip');

    let response = this.http.get(this.configService.hostAddress + `Download/FinalistDetailsReport?AuthToken=${authToken}&AppIdList=${applicationIdList}`,
        { headers: headers, observe: 'response', responseType: 'blob' }).pipe(catchError(this.handleError));

    return response;
}
angular asp.net-core-webapi memorystream migradoc c#-ziparchive
1个回答
0
投票

我发现了问题所在。当然这是一个愚蠢的想法。问题是我在 GET 函数中向服务器发送了一个数组,但我没有正确处理它。我不知道我怎么没有注意到列表没有正确填充。我想我太专注于困难的部分而没有注意到小事情。因此,为了解决这个问题,我只是发送了奖学金 ID 并进行了快速数据库查询以获取我需要的所有应用程序 ID。

© www.soinside.com 2019 - 2024. All rights reserved.