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

如何在Flutter移动应用中集成Jasper Report?

Flutter 连接并查看 Jasper Report 的实现方案

核心思路

Flutter客户端无法直接解析或渲染Jasper Report模板,需借助后端服务完成报表编译、数据填充与导出,再由Flutter调用接口获取成品报表(如PDF、HTML)并展示。


1. 后端实现(以Java Spring Boot为例)

通过后端生成报表文件并提供接口供Flutter调用:

import net.sf.jasperreports.engine.*;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
public class ReportController {

    // 模拟获取报表数据
    private List<ReportData> getReportData(@RequestParam String userId) {
        // 实际场景可从数据库或其他API查询数据
        return List.of(new ReportData("用户" + userId, "2024-05-20", 100.0));
    }

    @GetMapping("/report/pdf")
    public ResponseEntity<byte[]> generatePdfReport(@RequestParam String userId) throws JRException {
        // 加载预编译的Jasper模板(.jasper文件)
        InputStream jasperStream = getClass().getResourceAsStream("/reports/UserReport.jasper");
        JasperReport jasperReport = (JasperReport) JRLoader.loadObject(jasperStream);

        // 设置报表参数
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("UserId", userId);
        parameters.put("ReportDate", "2024-05-20");

        // 填充数据
        JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(getReportData(userId));
        JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, dataSource);

        // 导出为PDF字节流
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        JasperExportManager.exportReportToPdfStream(jasperPrint, outputStream);

        // 设置响应头,支持在线预览或下载
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_PDF);
        headers.setContentDispositionFormData("inline", "user_report.pdf");

        return new ResponseEntity<>(outputStream.toByteArray(), headers, HttpStatus.OK);
    }
}

// 数据实体类
class ReportData {
    private String username;
    private String orderDate;
    private Double amount;

    public ReportData(String username, String orderDate, Double amount) {
        this.username = username;
        this.orderDate = orderDate;
        this.amount = amount;
    }

    // 省略getter方法
}

2. Flutter 端调用与展示

使用http请求后端接口,通过pdf_flutter展示PDF报表:

依赖配置

在pubspec.yaml中添加:

dependencies:
  http: ^1.2.1
  pdf_flutter: ^1.2.1

代码实现

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:pdf_flutter/pdf_flutter.dart';

class JasperReportView extends StatefulWidget {
  final String userId;

  const JasperReportView({super.key, required this.userId});

  @override
  State<JasperReportView> createState() => _JasperReportViewState();
}

class _JasperReportViewState extends State<JasperReportView> {
  Uint8List? _pdfBytes;
  bool _isLoading = true;

  @override
  void initState() {
    super.initState();
    _fetchReport();
  }

  Future<void> _fetchReport() async {
    try {
      final response = await http.get(
        Uri.parse("http://你的后端IP:端口/report/pdf?userId=${widget.userId}"),
      );
      if (response.statusCode == 200) {
        setState(() {
          _pdfBytes = response.bodyBytes;
          _isLoading = false;
        });
      }
    } catch (e) {
      setState(() {
        _isLoading = false;
      });
      // 处理请求错误,如弹窗提示
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text("报表加载失败: $e")),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("用户报表")),
      body: _isLoading
          ? const Center(child: CircularProgressIndicator())
          : _pdfBytes != null
              ? PDF.bytes(
                  _pdfBytes!,
                  fitPolicy: FitPolicy.BOTH,
                )
              : const Center(child: Text("报表数据为空")),
    );
  }
}

3. 关键注意事项

  • 开发阶段确保Flutter设备与后端服务处于同一局域网,使用后端本地IP而非localhost
  • 生产环境需使用HTTPS接口,避免数据传输风险
  • 若需要导出Excel/Word格式报表,可在后端更换Jasper的导出工具类(如JasperExportManager.exportReportToXlsStream)
  • 复杂报表建议提前编译.jrxml模板为.jasper文件,提升后端生成效率

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 14:45:42