You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将REST控制器中Jasper Reports生成的Base64 PDF传输至Ionic 3应用并打开

实现Ionic 3加载后端Base64格式PDF的方案

我来给你梳理几个实现这个需求的靠谱方案,分后端和前端两部分来说明:

一、后端REST控制器处理(Jasper Reports转PDF再转Base64)

假设你用Java Spring Boot作为后端,这里给个核心代码示例(其他后端语言逻辑类似,都是先生成PDF二进制数据再编码为Base64):

@GetMapping("/generate-pdf-base64")
public ResponseEntity<String> generatePdfAsBase64() throws JRException, IOException {
    // 1. 加载Jasper报表模板并填充参数
    InputStream jasperStream = getClass().getResourceAsStream("/reports/your-report.jasper");
    Map<String, Object> parameters = new HashMap<>();
    // 这里填充你的报表参数,比如数据源、自定义参数等
    
    // 2. 生成PDF字节数组
    JasperPrint jasperPrint = JasperFillManager.fillReport(jasperStream, parameters, new JREmptyDataSource());
    byte[] pdfBytes = JasperExportManager.exportReportToPdf(jasperPrint);
    
    // 3. 转成Base64字符串返回
    String base64Pdf = Base64.getEncoder().encodeToString(pdfBytes);
    return ResponseEntity.ok(base64Pdf);
}

二、前端Ionic 3的几种实现方案

方案1:直接在WebView中打开(无需保存文件)

利用Ionic的InAppBrowser插件直接打开Base64格式的PDF,不用先存本地文件,步骤如下:

  1. 安装对应版本的插件(Ionic 3要适配@4版本的Native插件):
ionic cordova plugin add cordova-plugin-inappbrowser
npm install @ionic-native/in-app-browser@4
  1. 代码实现:
import { InAppBrowser } from '@ionic-native/in-app-browser';
import { HttpClient } from '@angular/common/http';

constructor(private iab: InAppBrowser, private http: HttpClient) {}

openPdfFromBase64() {
  this.http.get('http://你的后端接口地址/generate-pdf-base64', { responseType: 'text' }).subscribe(base64Data => {
    // 构造PDF的data URI
    const pdfDataUri = `data:application/pdf;base64,${base64Data}`;
    // 用InAppBrowser打开,_blank表示在新窗口打开
    const browser = this.iab.create(pdfDataUri, '_blank', {
      location: 'yes',
      zoom: 'yes'
    });
    browser.show();
  }, error => {
    console.error('获取PDF失败:', error);
  });
}

这个方案的优势是简单快速,不需要操作本地文件;缺点是部分旧设备的WebView对大体积Base64的支持可能有限。

方案2:保存为本地文件后用Document Viewer打开

这是你提到的方案,给你补全具体实现代码:

  1. 安装所需插件:
# 文件操作插件
ionic cordova plugin add cordova-plugin-file
npm install @ionic-native/file@4

# 文档查看器插件
ionic cordova plugin add cordova-plugin-document-viewer
npm install @ionic-native/document-viewer@4
  1. 代码实现:
import { File } from '@ionic-native/file';
import { DocumentViewer } from '@ionic-native/document-viewer';
import { HttpClient } from '@angular/common/http';

constructor(private file: File, private documentViewer: DocumentViewer, private http: HttpClient) {}

saveAndOpenPdf() {
  this.http.get('http://你的后端接口地址/generate-pdf-base64', { responseType: 'text' }).subscribe(base64Data => {
    // 将Base64转为Blob格式
    const blob = this.base64ToBlob(base64Data, 'application/pdf');
    // 定义文件名和存储路径(用应用私有目录,跨平台通用)
    const fileName = 'report.pdf';
    const filePath = this.file.dataDirectory;

    // 写入本地文件
    this.file.writeFile(filePath, fileName, blob, { replace: true }).then(() => {
      // 调用Document Viewer打开文件
      const options = {
        title: '报表查看'
      };
      this.documentViewer.viewDocument(`${filePath}${fileName}`, 'application/pdf', options);
    }).catch(error => {
      console.error('保存文件失败:', error);
    });
  }, error => {
    console.error('获取PDF失败:', error);
  });
}

// Base64转Blob的工具方法
private base64ToBlob(base64: string, contentType: string): Blob {
  const byteCharacters = atob(base64);
  const byteArrays = [];
  for (let offset = 0; offset < byteCharacters.length; offset += 512) {
    const slice = byteCharacters.slice(offset, offset + 512);
    const byteNumbers = new Array(slice.length);
    for (let i = 0; i < slice.length; i++) {
      byteNumbers[i] = slice.charCodeAt(i);
    }
    const byteArray = new Uint8Array(byteNumbers);
    byteArrays.push(byteArray);
  }
  return new Blob(byteArrays, { type: contentType });
}

这个方案兼容性更好,适合大文件,而且Document Viewer的体验更接近原生应用。

方案3:用PDF.js集成渲染(自定义查看器)

如果需要定制化的PDF查看体验(比如添加自定义工具栏、标注功能),可以集成PDF.js到Ionic 3中:

  1. 安装兼容Ionic 3的PDF.js版本:
npm install pdfjs-dist@2.0.943 --save

(注意要把node_modules/pdfjs-dist/build/pdf.worker.js复制到项目的assets目录下)

  1. 代码示例(在页面中渲染PDF):
import { HttpClient } from '@angular/common/http';
declare var pdfjsLib: any;

constructor(private http: HttpClient) {}

renderPdf() {
  this.http.get('http://你的后端接口地址/generate-pdf-base64', { responseType: 'text' }).subscribe(base64Data => {
    // 将Base64转为ArrayBuffer
    const pdfData = atob(base64Data);
    const arrayBuffer = new ArrayBuffer(pdfData.length);
    const uint8Array = new Uint8Array(arrayBuffer);
    for (let i = 0; i < pdfData.length; i++) {
      uint8Array[i] = pdfData.charCodeAt(i);
    }

    // 初始化PDF.js
    pdfjsLib.GlobalWorkerOptions.workerSrc = 'assets/pdf.worker.js';

    pdfjsLib.getDocument(arrayBuffer).promise.then(pdf => {
      // 渲染第一页,如需分页可循环处理
      pdf.getPage(1).then(page => {
        const canvas = document.getElementById('pdf-canvas') as HTMLCanvasElement;
        const ctx = canvas.getContext('2d');
        const viewport = page.getViewport({ scale: 1.5 });
        canvas.height = viewport.height;
        canvas.width = viewport.width;

        page.render({
          canvasContext: ctx,
          viewport: viewport
        });
      });
    });
  }, error => {
    console.error('获取PDF失败:', error);
  });
}

然后在页面模板中添加用于渲染的canvas:

<canvas id="pdf-canvas"></canvas>

这个方案适合需要深度定制的场景,但需要自己处理分页、缩放等细节功能。

总结

  • 追求简单快速:选方案1;
  • 看重原生体验和兼容性:选方案2;
  • 需要自定义PDF查看功能:选方案3。

内容的提问来源于stack exchange,提问作者ezolton

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 08:12:53