本帖最后由 lucas.Yan 于 2024-12-20 13:40 编辑
应用场景:客户在创建前后端分离的应用时,前端只用于做一些基本的数据展示,如果涉及大量的数据或报表生成,建议放在服务器端展示,本文主要分享如何在服务器端使用ActiveReportsJS 实现报表导出PDF功能 Demo下载
运行Demo 2 配置Java项目 3 运行maven 4 修改代码中的WebDriver地址 5 运行程序,访问index接口 环境准备:Maven3、Tomcat9.0.88、Java17、Edge浏览器和对应版本的WebDriver。
主要代码: 利用selenium的无头浏览器调用报表的导出方法,将返回的PDF数据流保存为文件形式。然后通过调用服务器的打印程序进行打印。
- package Servlet;
- import org.apache.pdfbox.pdmodel.PDDocument;
- import org.apache.pdfbox.printing.PDFPageable;
- import org.openqa.selenium.JavascriptExecutor;
- import org.openqa.selenium.WebDriver;
- import org.openqa.selenium.edge.EdgeDriver;
- import org.openqa.selenium.edge.EdgeOptions;
- import javax.servlet.ServletException;
- import javax.servlet.annotation.WebServlet;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import java.awt.*;
- import java.awt.print.PrinterException;
- import java.awt.print.PrinterJob;
- import java.io.File;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.util.Base64;
- @WebServlet(name = "index", value = "/index")
- public class index extends HttpServlet {
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
- EdgeOptions edgeOptions = new EdgeOptions();
- edgeOptions.addArguments("--headless");
- edgeOptions.addArguments("--disable-gpu");
- edgeOptions.addArguments("--no-sandbox");
- //resources文件夹下有一份,替换使用。
- System.setProperty("webdriver.edge.driver", "C:\\Users\\LucasYan\\Desktop\\客户资源\\后端导出arjs-java\\src\\main\\resources\\msedgedriver.exe");
- String resultString = getPDFString(edgeOptions);
- resp.setContentType("text/plain");
- resp.setCharacterEncoding("UTF-8");
- resp.getWriter().write(resultString);
- //去掉前缀,转换为PDF文件并保存。
- String pdfstring = resultString.replace("data:application/pdf;base64,", "");
- byte[] pdfBytes = Base64.getDecoder().decode(pdfstring);
- File file = new File("output.pdf");
- try (FileOutputStream fos = new FileOutputStream(file)) {
- fos.write(pdfBytes);
- // 打开PDF文档
- PDDocument document = PDDocument.load(file);
- // 创建一个PrinterJob
- PrinterJob job = PrinterJob.getPrinterJob();
- // 设置页面格式
- job.setPageable(new PDFPageable(document));
- // 尝试打印文档
- // job.print();
- // 关闭文档
- document.close();
- System.out.println("PDF 文件已成功生成:output.pdf");
- } catch (IOException e) {
- e.printStackTrace();
- }
- // catch (PrinterException e){
- // e.printStackTrace();
- // }
- }
- private static String getPDFString(EdgeOptions edgeOptions) {
- WebDriver driver = new EdgeDriver(edgeOptions);
- String targetUrl = "http://localhost:8080/static/arjs.html"; // Replace with actual URL
- driver.get(targetUrl);
- // 执行页面上的脚本呢
- JavascriptExecutor jsExecutor = (JavascriptExecutor) driver;
- Object result = jsExecutor.executeScript(
- "var callback = arguments[arguments.length - 1];" +
- "return generatePDF().then(callback);"); // Replace with actual function name
- return result != null ? result.toString() : "";
- }
- }
复制代码
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8" />
- <meta http-equiv="X-UA-Compatible" content="IE=edge" />
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
- <title>Proposal Generation</title>
- <link
- rel="stylesheet"
- href="https://cdn.grapecity.com/activereportsjs/5.0.0/styles/ar-js-ui.css"
- type="text/css"
- />
- <!-- <link-->
- <!-- rel="stylesheet"-->
- <!-- href="https://cdn.grapecity.com/activereportsjs/5.0.0/styles/ar-js-designer.css"-->
- <!-- type="text/css"-->
- <!-- />-->
- <link
- rel="stylesheet"
- href="https://cdn.grapecity.com/activereportsjs/5.0.0/styles/ar-js-viewer.css"
- type="text/css"
- />
- <script src="https://cdn.grapecity.com/activereportsjs/5.0.0/dist/ar-js-core.js"></script>
- <!-- <script src="https://cdn.grapecity.com/activereportsjs/5.0.0/dist/ar-js-designer.js"></script>-->
- <script src="https://cdn.grapecity.com/activereportsjs/5.0.0/dist/ar-js-pdf.js"></script>
- <script src="https://cdn.grapecity.com/activereportsjs/5.0.0/dist/ar-js-tabular-data.js"></script>
- <script src="https://cdn.grapecity.com/activereportsjs/5.0.0/dist/ar-js-html.js"></script>
- <script type="text/javascript" src="./datasource.js"></script>
- </head>
- <body>
- <embed id="pdf" type="application/pdf" width="100%" height="800px" />
- </body>
- <script type="text/javascript">
- const ARJS = MESCIUS.ActiveReportsJS.Core;
- const fonts = [
- {
- name: '微软雅黑',
- locals: ['Microsoft YaHei', 'SimSun Regular'],
- source: './fonts/Chinese.ttf',
- },
- {
- name: 'Sinhala',
- locals: ['Microsoft YaHei', 'SimSun Regular'],
- source: './fonts/Chinese.ttf',
- },
- {
- name: 'Arial',
- weight: 'bold',
- style: 'italic',
- source: './fonts/arialbi.ttf',
- },
- {
- name: 'Arial',
- style: 'italic',
- source: './fonts/ariali.ttf',
- },
- {
- name: 'Arial',
- weight: 'bold',
- source: './fonts/arialbd.ttf',
- },
- {
- name: 'Arial',
- source: './fonts/arial.ttf',
- },
- ];
- ARJS.FontStore.registerFonts(fonts);
- const settings = {
- info: {
- title: 'Invoice List',
- subject: 'This is the Invoice List',
- author: 'John K',
- keywords: 'PDF; import; export',
- },
- fonts: fonts,
- };
- const lang = 'HK';
- function blob2base64(blob) {
- return new Promise((resolve, reject) => {
- var reader = new FileReader();
- reader.onloadend = () => {
- resolve(reader.result);
- };
- reader.onerror = () => {
- reject(reader.err);
- };
- reader.readAsDataURL(blob);
- });
- }
- async function generateProposal(mainReport) {
- const start = new Date();
- console.log(`start generate proposal inner puppeteer HTML ${start}`);
- const PDF = MESCIUS.ActiveReportsJS.PdfExport;
- const pageReport = new ARJS.PageReport();
- try {
- await pageReport.load(mainReport);
- if ('LicenseError' === pageReport.name) {
- throw new Error('License Error');
- }
- const pageDocument = await pageReport.run();
- console.log('page report randered completed, start export the PDF');
- const result = await PDF.exportDocument(pageDocument, settings, pageNum => {
- console.log(`exporting PDF version at page ${pageNum}`);
- });
- console.log(`pdf document exported completed, cost ${Date.now() - start}ms`);
- return blob2base64(result.data);
- } catch (e) {
- console.error(`error occured while generate the proposal, ${e}`);
- throw e;
- }
- }
- </script>
- <script>
- async function generatePDF() {
- return await generateProposal('templates/123.rdlx-json');
- }
- </script>
- </html>
复制代码
|