需要下载报表设计工具:Jaspersoft® Studio | Jaspersoft Community
大概分为三个部分:
2.Spring boot 读取报表并返回前端,使用到jasperreports依赖;
3.vue3 读取后端文件流进行在线展示,这里用到了pdfjs-dist插件(注意:网上搜资料有的使用vue-pdf,但是它不支持vue3)
2.Spring boot 读取报表并返回文件流到前端
把第一步获取到的字体包Fonts.jar放到Resource下,并Add as Library。
导出的.jasper文件也要拿过来。
然后开始编码,
1)导入依赖包
<dependency>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports</artifactId>
<version>6.20.6</version>
</dependency>
2)编写代码
@PostMapping("/report")
public void report(SearchModel model,
HttpServletResponse response) throws Exception{
ServiceResult result=new ServiceResult();
//获取.jasper文件
ClassPathResource resource=new ClassPathResource("jaspers"+ File.separator+"test2"+".jasper");
InputStream jasperStream=resource.getInputStream();
JasperReport jasperReport=(JasperReport) JRLoader.loadObject(jasperStream);
//获取数据,并转成json格式
HashMap<String, Object> hashMap = new HashMap<>();
GridModel<t_role> lstEntity=service.grid(new SearchModel());
//转换时间格式
JSONObject.DEFFAULT_DATE_FORMAT="yyyy-MM-dd HH:mm:ss.SSS";
String json=JSON.toJSONString(lstEntity, SerializerFeature.WriteDateUseDateFormat);
InputStream inputStream = new ByteArrayInputStream(json.getBytes("UTF-8"));
hashMap.put("JSON_INPUT_STREAM",inputStream);
//把数据源填充到报表中
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, hashMap);
//设置响应头,并输出文件流
response.setContentType("application/pdf; charset=utf-8");
response.setHeader("content-disposition", "inline;filename=test.pdf" );
final OutputStream outputStream=response.getOutputStream();
JasperExportManager.exportReportToPdfStream(jasperPrint,outputStream);
}
3.vue3 读取后端文件流进行在线展示
下载pdf-dist文件:Releases · mozilla/pdf.js (github.com)
用的pdfjs-3.11.174-dist.zip,解压后,把build、web文件夹放到vue中的public/static文件夹下
编写vue文件(这里像<lay-form>标签,我使用了layui框架)
<template>
<div>
<lay-form :model="searchData" :pane="true">
<lay-form-item label="名称" prop="f_name" mode="inline">
<lay-input v-model="searchData.f_name"></lay-input>
</lay-form-item>
<lay-form-item label="操作人" prop="f_last_user" mode="inline">
<lay-input v-model="searchData.f_last_user"></lay-input>
</lay-form-item>
<lay-form-item mode="inline">
<lay-button type="primary" @click="btnOpen">查询</lay-button>
</lay-form-item>
</lay-form>
<input type="hidden" id="formData" :value="JSON.stringify(toRaw(searchData))">
<iframe id="myIframe" :src="'static/pdf/web/viewer.html?file=' + fileUrl"
style="width: 100%; height: 440px"></iframe>
</div>
</template>
<script setup>
import { reactive, ref, toRaw } from 'vue';
const fileUrl = ref('')
const searchData = reactive({
f_name: '',
f_last_user: ''
})
const btnOpen = () => {
fileUrl.value = '/api/test/report?i' + parseInt(new Date().getTime() / 1000) + ''
}
</script>
<style lang="scss" scoped></style>
修改了pdf.js的一些源码:
1.增加header
2.把把默认的get请求换成post,并传参数给后台
效果图: