首页 > 解决方案 > 将 pdf 从 Django 后端传递到 Angular 前端

问题描述

我无法为我的案例提供任何类似问题的解决方案。我想使用 django 从文件系统加载 pdf 并通过 API 调用将其返回给 Angular,以便显示它。我的 Django 代码差不多:

class LoadPdfViewSet(views.APIView):
    def get(self, request):
        # some code here here
        response = FileResponse(open(path_to_pdf, 'rb').read())
        response.headers = {   
            'Content-Type': 'application/pdf',
            'Content-Disposition': 'attachment;filename="report.pdf"',
        }
        response.as_attachment = True
        return response

而在 Angular 方面,我有一项服务可以做到这一点:

export class LoadPdfService {
    constructor(
        private http: HttpClient
    ) {}

    getPdf(): Observable<Blob> {
        const params = new HttpParams({
            fromObject: { 
                responsetype: 'arraybuffer' 
                // other stuff here
            }
        })
        return self.http.get<Blob>(loadpdf_api_url, {params}).pipe(catchError(self.myErrorHandler))
    }
}

以及一个尝试像这样打开 pdf 的组件:

export class MyComponent {
    constructor(
        public loadPdfService: LoadPdfService
    ) {}

    download_pdf() {
        let call = self.loadPdfService.getPdf();
        call.subscribe( (response:Blob) => {
            if (window.navigator && window.navigator.msSaveOrOpenBlob) { // for IE
                window.navigator.msSaveOrOpenBlob(blob, "report.pdf");
            } else {
                let pdfUrl = URL.createObjectURL(blob)
                window.open(pdfUrl, '_blank')
                URL.revokeObjectURL(pdfUrl);    
            }            
        }
    }
}

但什么也没发生。我还尝试在 django 端使用不同的响应和直通渲染器,以及Observable<Response>像这样的.then()回调

response.arrayBuffer().then(buffer => new Blob([buffer], {type: 'application/pdf'}))

在角度方面。有时我设法打开新窗口/标签,但无法显示 pdf。

标签: djangoangularpdfdjango-rest-frameworkhttpresponse

解决方案


我终于弄明白了。在python部分,read()可以毫无问题地删除。问题在于服务响应类型和响应映射:

getPdf(): Observable<Blob> {
    const options = {
        params: new HttpParams({
            fromObject: {
                // my own parameters here
            }
        }),
        responseType: 'blob' as 'json'
    };

    return this.http.get(this.url, options).pipe(
        map(response => response as Blob),
        catchError(this.myErrorHandler))
}

推荐阅读