报表如何批量导出 pdf

需求说明

报表展现后可以通过工具栏中的导出按钮将当前展现的报表导出成 pdf 文件,但是在实际使用中通常会要求报表不需要展现,直接通过一些操作将报表导出成 pdf 文件,并且往往会要求批量导出成 pdf 文件,下面通过几个示例介绍下报表不展现,如何批量生成 excel 文件。

实现这种需求一般要用到 api 方式,批量生成 excel 文件,按照方式上来分大体上可以分为三类:

一:单表导出单 pdf 多页

二:多表导出单 pdf 多页

三:多表导出多 pdf 文件

单表多页

此种方式通常是报表格式固定,然后根据某个参数对数据过滤,导出 pdf 时需要导出多个参数的数据,并且每个参数的数据放到同一个 pdf 的不同页里,比如本例中按照地区统计订单信息,要求导出时每个地区数据导出到一个 pdf 页中,下面看下这种做法:

报表设计界面不必多说,按照需求设计就行,如下图:

报表中增加一个参数:area,用于接收地区参数,然后在数据集中通过这个参数过滤数据就行。

Api 中用到 jsp 代码如下:

<%@ page contentType="text/html;charset=UTF-8" %>

<%@ page import="com.raqsoft.report.model.*"%>

<%@ page import="com.raqsoft.report.usermodel.*"%>

<%@ page import="com.raqsoft.report.view.*"%>

<%@ page import="com.raqsoft.report.util.*"%>

<%@ page import="com.raqsoft.report.view.pdf.PdfReport"%>

<%@ page import="java.io.*" %>

<%

 String report = request.getParameter( "report" );//获取报表名称

if(report==null) report="订单.rpx";//如果url上报表名为空,则取订单表

String fileName=report.substring(0,report.length()-4);//读取文件名,用于设置excel名称

String reportName = request.getRealPath("WEB-INF\\\reportFiles\\\"+report);//

String exportPath=request.getRealPath("/export");//在应用根目录下建export目录,放置导出文件

ReportDefine rd = (ReportDefine)ReportUtils.read(reportName);//读取报表

String areas="华北,东北,西北,华南,西南";//此例按照地区循环,实际中可以接收其他参数,也可以从数据库中获取数据

String\[\] area=areas.split(",");

OutputStream os = null;

os = new FileOutputStream(exportPath+"/"+fileName+".pdf");

PdfReport er=new PdfReport(os);

for(int i=0;i<area.length;i++){//按照地区做循环

Context cxt = new Context();

cxt.setParamValue("area",area\[i\]);//area是报表中定义参数,此处设置参数值

  Engine engine = new Engine(rd, cxt); //构造报表引擎

  IReport iReport = engine.calc(); //运算报表

 er.export(iReport);//将报表结果设置到pdf中

}

er.save();

 os.flush();

 os.close();

%>

 

这样,就会在应用根目录的 export 目录下生成对应的 pdf 文件

多表多页

此种情况应用于导出的 pdf 由多个报表组成,然后每个 excel 报表导出到 pdf 中不同页中,并且有可能每个报表的参数不同(如果参数相同,那么和示例一类似,只是按报表名称循环就行),下面看下具体实现过程:

由于不同报表参数可能会不同,所以在 api 中解析每个报表以及对应参数难度会比较大,此例要求通过 url 访问报表时,按照特定格式访问,比如:

http://localhost:6868/demo/reportJsp/exportPdf1.jsp?report={无参数报表名 1}{无参数报表名 2}{报表 1( 参数 1=value1; 参数 2=value2;…)}{报表 2( 参数 1=value1; 参数 2=value2;…)},比如:http://localhost:6868/demo/reportJsp/exportPdf1.jsp?report={test1.rpx}{test2.rpx(arg1=11;arg2=22;arg3=33)}这种方式,现在在高版本的 tomcat 中,会有一些特殊符号的限定,使用时可以将 {} 转换成对应的 urlencode 方式,{为 %7B,}为 %7B,如果有其他值的话,做对应转换就行,url 设置完成后,接下来就看下如何解析这个 url,并且批量生成 pdf,代码如下:

<%@ page contentType="text/html;charset=UTF-8" %>

<%@ page import="com.raqsoft.report.model.*"%>

<%@ page import="com.raqsoft.report.usermodel.*"%>

<%@ page import="com.raqsoft.report.view.*"%>

<%@ page import="com.raqsoft.report.util.*"%>

<%@ page import="com.raqsoft.report.view.pdf.PdfReport"%>

<%@ page import="java.io.*" %>

<%

 //此JSP参数格式为:report={无参数报表名1}{无参数报表名2}{报表1(参数1=value1;参数2=value2;...)}{报表2(参数1=value1;参数2=value2;...)}

request.setCharacterEncoding( "UTF-8" );

 String report = request.getParameter( "report" );

 if( report == null || report.trim().length() == 0 ) throw new Exception( "请输入报表文件名及参数串report={无参数报表名}{报表1(参数1=value1;参数2=value2;...)}{报表2(参数1=value1;参数2=value2;...)}..." );

String exportPath=request.getRealPath("/export");//在应用根目录下建export目录,放置导出文件

String report1=report.replace("}","");//去掉串中的}

String report2=report1.substring(1,report1.length());//去掉串中的最左侧的{

String\[\] a=report2.split("\\\{");//此时串中多个报表之间用{分隔,所以此处按照该符号split生成数组

OutputStream os = null;

os = new FileOutputStream(exportPath+"/test.pdf");

PdfReport er=new PdfReport(os);

for(int i=0;i<a.length;i++){//按数组进行循环,也就是按报表循环

if(a\[i\].lastIndexOf("(")<=0)//判断分割后的子串中是否包含(,如包含,代表有参数,不包含,则没有参数

{

String reportPath = request.getRealPath("WEB-INF\\\reportFiles\\\"+a\[i\]);//获取报表路径

 String sheetName=a\[i\].substring(0,a\[i\].length()-4);//获取sheet名称

 ReportDefine rd = (ReportDefine)ReportUtils.read(reportPath);//读取报表

 Context cxt = new Context();

 Engine engine = new Engine(rd, cxt); //构造报表引擎

IReport iReport = engine.calc(); //计算报表

er.export(sheetName,iReport);//将报表结果放入sheet

}

else{

 System.out.println("报表有参数,报表名为="+a\[i\].split("\\\(")\[0\]);//如果有参数,则按(字符split,左侧为报表名

 String reportPath = request.getRealPath("WEB-INF\\\reportFiles\\\"+a\[i\].split("\\\(")\[0\]);

 String sheetName=a\[i\].split("\\\(")\[0\].substring(0,a\[i\].split("\\\(")\[0\].length()-4);

 ReportDefine rd = (ReportDefine)ReportUtils.read(reportPath);

 Context cxt = new Context();

 String\[\] cs=a\[i\].split("\\\(")\[1\].replace(")","").split(";");//右侧为参数串,并且去掉参数串的),多个参数用;隔开,所以此处按照;split

 for(int j=0;j<cs.length;j++){//按参数循环

 cxt.setParamValue(cs\[j\].split("=")\[0\],cs\[j\].split("=")\[1\]);//设置参数

 }

 Engine engine = new Engine(rd, cxt); //构造报表引擎

IReport iReport = engine.calc();

er.export(iReport);

}

}

er.save();

 os.flush();

 os.close();

%>

 

多表多 pdf

此种方式和示例二类似,在实际使用中导出 pdf 时要求每个报表导出成不同的 pdf 文件,但是后续可能会涉及到下载问题,所以此种方式一般是要建立个临时目录,然后将多个 pdf 放到临时目录内,可以进行打包下载。具体代码如下:

<%@ page contentType="text/html;charset=UTF-8" %>

<%@ page import="com.raqsoft.report.model.*"%>

<%@ page import="com.raqsoft.report.usermodel.*"%>

<%@ page import="com.raqsoft.report.view.*"%>

<%@ page import="com.raqsoft.report.util.*"%>

<%@ page import="com.raqsoft.report.view.excel.ExcelReport"%>

<%

 //此JSP参数格式为:report={无参数报表名1}{无参数报表名2}{报表1(参数1=value1;参数2=value2;...)}{报表2(参数1=value1;参数2=value2;...)}

request.setCharacterEncoding( "UTF-8" );

 String report = request.getParameter( "report" );

 if( report == null || report.trim().length() == 0 ) throw new Exception( "请输入报表文件名及参数串report={无参数报表名}{报表1(参数1=value1;参数2=value2;...)}{报表2(参数1=value1;参数2=value2;...)}..." );

String exportPath=request.getRealPath("/export");//在应用根目录下建export目录,放置导出文件

String fileName=Double.toString(Math.random()*100000000).toString().substring(0,6);

String pdfPath=exportPath+"\\\"+fileName;

java.io.File file = new java.io.File(pdfPath);

 if(!file.exists()) {

 file.mkdirs();

 } else {

 }

String report1=report.replace("}","");//去掉串中的}

String report2=report1.substring(1,report1.length());//去掉串中的最左侧的{

String\[\] a=report2.split("\\\{");//此时串中多个报表之间用{分隔,所以此处按照该符号split生成数组

ExcelReport er=new ExcelReport();

for(int i=0;i<a.length;i++){//按数组进行循环,也就是按报表循环

if(a\[i\].lastIndexOf("(")<=0)//判断分割后的子串中是否包含(,如包含,代表有参数,不包含,则没有参数

{

String reportPath = request.getRealPath("WEB-INF\\\reportFiles\\\"+a\[i\]);//获取报表路径

 String sheetName=a\[i\].substring(0,a\[i\].length()-4);//获取报表名称

 ReportDefine rd = (ReportDefine)ReportUtils.read(reportPath);//读取报表

 Context cxt = new Context();

 Engine engine = new Engine(rd, cxt); //构造报表引擎

IReport iReport = engine.calc(); //计算报表

ReportUtils.exportToPDF(pdfPath+"/"+sheetName+".pdf",iReport);

}

else{

 System.out.println("报表有参数,报表名为="+a\[i\].split("\\\(")\[0\]);//如果有参数,则按(字符split,左侧为报表名

 String reportPath = request.getRealPath("WEB-INF\\\reportFiles\\\"+a\[i\].split("\\\(")\[0\]);

 String sheetName=a\[i\].split("\\\(")\[0\].substring(0,a\[i\].split("\\\(")\[0\].length()-4);

 ReportDefine rd = (ReportDefine)ReportUtils.read(reportPath);

 Context cxt = new Context();

 String\[\] cs=a\[i\].split("\\\(")\[1\].replace(")","").split(";");//右侧为参数串,并且去掉参数串的),多个参数用;隔开,所以此处按照;split

 for(int j=0;j<cs.length;j++){//按参数循环

 cxt.setParamValue(cs\[j\].split("=")\[0\],cs\[j\].split("=")\[1\]);//设置参数

 }

 Engine engine = new Engine(rd, cxt); //构造报表引擎

IReport iReport = engine.calc();

ReportUtils.exportToPDF(pdfPath+"/"+sheetName+".pdf",iReport);

}

}

%>

 

打包下载

文件生成到对应目录下后,可以自己单独做个链接指向这个 pdf 文件下载,也可以直接生成 pdf 文件后直接进行下载,在对应 jsp 文件中增加如下代码:

response.setContentType("application/msword");

 response.setHeader("Content-disposition","attachment; filename="+java.net.URLEncoder.encode(fileName+".pdf", "UTF-8"));

 BufferedInputStream bis = null;

 BufferedOutputStream bos = null;

 try {

 bis = new BufferedInputStream(new FileInputStream( exportPath+"/"+fileName+".pdf"));

 bos = new BufferedOutputStream(response.getOutputStream());

 byte\[\] buff = new byte\[2048\];

 int bytesRead;

 while(-1 != (bytesRead = bis.read(buff, 0, buff.length))) {

 bos.write(buff,0,bytesRead);

 }

 } catch(final IOException e) {

 System.out.println ( "出现IOException." + e );

 } finally {

 if (bis != null)

 bis.close();

 if (bos != null)

 bos.close();

 }

 System.out.println ( "下载完成----------------" );

File file = new File(exportPath+"/"+fileName+".pdf");

if (file.exists()) file.delete();//删除文件

 

实际应用中可能会需要将文件大成 zip 包方式,比如示例三,这个直接百度下 java 程序打 zip 包,然后下载 zip 包就行。

总结

本文中介绍了如何通过 api 将报表批量导出成 pdf 的方法,实际中也有可能生成 excel 或者 txt 等,思路是一样到,到时候换用不同的 api 就行。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 下面是一个使用 Python 的简单程序,可以批量下载巨潮资讯网上的 PDF 文件: ``` import requests import os # 巨潮资讯网 PDF 文件的 URL 前缀 url_prefix = 'http://www.cninfo.com.cn' # PDF 文件的 URL 列表 pdf_urls = [ '...', '...', '...', ] # 创建一个文件夹,用于保存 PDF 文件 if not os.path.exists('pdfs'): os.mkdir('pdfs') # 遍历每个 PDF 文件的 URL for pdf_url in pdf_urls: pdf_data = requests.get(url_prefix + pdf_url).content pdf_path = os.path.join('pdfs', pdf_url.split('/')[-1]) with open(pdf_path, 'wb') as f: f.write(pdf_data) ``` 这个程序需要安装 `requests` 库,可以使用 `pip install requests` 命令进行安装。请注意,下载大量文件可能会对网站造成压力,并且有可能违反网站的使用规则,请谨慎使用。 ### 回答2: 巨潮资讯网是一个提供各类金融和财务信息的网站,用户可以通过该网站下载PDF格式的文件。如果需要批量下载PDF文件,可以使用Python语言编写一个程序来实现。 下面是一个示例程序的逻辑: 1. 安装必要的Python库,如requests和beautifulsoup4,用于发送请求和解析HTML页面。 2. 导入所需的库和模块。 ```python import requests from bs4 import BeautifulSoup ``` 3. 设置基本请求和网址信息。 ```python base_url = 'http://www.cninfo.com.cn' search_url = '/new/fulltextSearch?notautosubmit=&keyWord=' ``` 4. 编写函数来获取搜索结果页面中的PDF下载链接。 ```python def get_pdf_links(keyword): search_url = base_url + search_url + keyword response = requests.get(search_url) soup = BeautifulSoup(response.text, 'html.parser') pdf_links = [] # 查找所有包含PDF链接的元素 for link in soup.find_all('a'): if link.get('href') and link.get('href').endswith('.pdf'): pdf_links.append(link.get('href')) return pdf_links ``` 5. 编写函数来下载PDF文件。 ```python def download_pdf(url, save_path): response = requests.get(url) with open(save_path, 'wb') as file: file.write(response.content) ``` 6. 编写主程序来批量下载PDF文件。 ```python keyword = input('请输入搜索关键词:') pdf_links = get_pdf_links(keyword) for index, link in enumerate(pdf_links): save_path = f'pdf{index+1}.pdf' download_pdf(base_url + link, save_path) print(f'{save_path} 下载完成!') ``` 以上是一个简单的Python程序,它使用了requests库发送HTTP请求,使用beautifulsoup4库解析HTML页面,以及使用基本的逻辑来提取和下载PDF文件。 请注意,该程序可能需要根据巨潮资讯网的具体网页结构进行调整,以确保其正常工作。此外,为了节约时间和带宽,你也可以在程序中添加一些检查和筛选条件,以仅下载你感兴趣的PDF文件。 ### 回答3: 巨潮资讯网是一个提供上市公司信息的网站,其中的PDF文件包含了各种公司的财务报表、公告等重要资料。我们可以使用Python编写一个程序来实现批量下载巨潮资讯网上的PDF文件。 首先,我们需要使用`requests`库来发送HTTP请求,并使用`re`库来进行正则表达式匹配。 ```python import requests import re ``` 然后,我们需要定义一个函数来下载PDF文件。这个函数将接收一个URL作为参数,并从该URL获取PDF文件的二进制数据,然后将数据保存到本地文件。 ```python def download_pdf(url): response = requests.get(url) if response.status_code == 200: filename = re.findall(r'filename=(.+)', response.headers['Content-Disposition'])[0] with open(filename, 'wb') as f: f.write(response.content) print(f"已下载文件:{filename}") else: print(f"下载失败:{response.status_code}") ``` 接下来,我们需要获取巨潮资讯网上的PDF文件的URL。我们可以使用`requests`库发送一个GET请求到巨潮资讯网的搜索页面,并使用正则表达式从返回的HTML中提取PDF文件的URL。 ```python def get_pdf_urls(keyword): url = f'http://www.cninfo.com.cn/new/fulltextSearch/full?searchkey={keyword}&sdate=&edate=&isfulltext=false&sortName=date&sortType=desc&pageNum=1' response = requests.get(url) if response.status_code == 200: pdf_urls = re.findall(r'<a\s+href="(/disk/(.+?\.PDF))".*?>', response.text) return pdf_urls else: print(f"获取URL失败:{response.status_code}") return [] ``` 最后,我们可以编写一个主函数来控制整个下载过程。该函数将接收一个关键字作为参数,然后获取包含该关键字的PDF文件的URL,并使用`download_pdf`函数来下载这些文件。 ```python def main(keyword): pdf_urls = get_pdf_urls(keyword) for url, _ in pdf_urls: download_pdf(f'http://www.cninfo.com.cn{url}') ``` 我们可以通过调用`main`函数并传入关键字来运行程序。 ```python if __name__ == '__main__': keyword = input('请输入关键字:') main(keyword) ``` 请注意,为了运行这个程序,你需要在安装Python的基础上安装`requests`库和`re`库。可以使用以下命令来安装这些库: ``` pip install requests ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值