Java调用Vue前端页面生成PDF文件的完整代码

 更新时间:2025年10月21日 08:26:55   作者:Aikes902  
在Vue应用中,将页面导出为PDF文件通常涉及到前端技术的组合,这篇文章主要介绍了Java调用Vue前端页面生成PDF文件的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下

一、业务背景

在实际业务使用中,有些情况下打印功能是由后端组装数据,前端整理数据生成pdf文件。此时如果某个功能需要后端再拿到生成的pdf进行下一步处理就不好实现。

比如后端需要拿到pdf文件发给CA厂商进行鉴权,如果在之前基础上增加新的交互逻辑整个流程就变得复杂冗余,于是我们考虑后端直接调用前端获取pdf文件

二、流程概览

页面点击触发——>后端组装参数调用Vue生成PDF——>前端收到请求解析参数绘制PDF——>后端拿到PDF文件进行后续业务处理(CA鉴权等)

其中关键的一点在于后端访问后需要等待多久再生成PDF,如果固定某个时间间隔可能会出现PDF没生成全或者已经生成完成但是还在等待浪费时间。

所以约定了一个属性,当前端页面渲染完成给这个属性打标记,后端读取标记成功后生成PDF。

三、环境准备

该功能需要依赖浏览器,我们以谷歌为例,确认好本地谷歌浏览器版本,下载对应的浏览器驱动。(驱动下载地址:Chrome for Testing availability

大版本必须一致(139),然后将下载好的驱动放到固定位置谷歌浏览器exe位置也需要摘出来,稍后需要在Java代码中配置。

四、后端代码

需要将驱动路径、浏览器路径,前端访问路径进行配置,前端访问路由可自行调整。以下是具体代码,整体流程简单需要调试的配置较多。

private String dllUrl;//存储驱动的根目录,完整路径代码拼接,可自行调整

private String mWebAddress;//存储前端访问页面,后续访问路由代码拼接,可自行调整

private String chromePath;//浏览器启动程序完整路径,可自行调整

package com.aikes.util;

import lombok.extern.slf4j.Slf4j;
import org.openqa.selenium.By;
import org.openqa.selenium.Pdf;
import org.openqa.selenium.PrintsPage;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.Duration;
import java.util.Base64;
import java.util.Collections;

/**
 * 调用vue页面获取PDF文件
 */
@Slf4j
@Service
public class WebAccessServerUtil {

    @Value("${dllUrl:D:/DLL}")
    private String dllUrl;

    @Value("${webAddress:http://127.0.0.1:8080/mcpc/ui/dist/index.html}")
    private String mWebAddress;

    @Value("${chromePath:C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe}")
    private String chromePath;

    public boolean getPdfFromWeb(String cPath,String cpk_notification,String cpk_emgency){

        log.info("根目录:" + dllUrl);
        log.info("Web端访问地址:" + mWebAddress);
        log.info("谷歌浏览器路径:" + chromePath);

        // 完全禁用WebDriverManager自动下载,手动指定驱动路径(避免版本冲突)
        System.setProperty("wdm.enabled", "false");
        // 手动指定本地ChromeDriver路径(替换为你的实际路径)
        //驱动版本需要和服务器浏览器版本对应   138.0.7204.158
        System.setProperty("webdriver.chrome.driver", dllUrl + File.separator + "chromedriver" + File.separator + "chromedriver.exe");
        System.setProperty("webdriver.chrome.bin", chromePath);

        // 配置浏览器选项(重点修复)
        ChromeOptions options = new ChromeOptions();
        options.addArguments("--headless=new"); // 新版headless模式
        options.addArguments("--disable-gpu");
        options.addArguments("--no-sandbox");
        options.addArguments("--disable-dev-shm-usage");
        options.addArguments("--remote-allow-origins=*"); // 允许跨域WebSocket
        options.setExperimentalOption("excludeSwitches", Collections.singletonList("enable-automation"));

        WebDriver driver = new ChromeDriver(options);
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(15)); // 最大等待10秒

        try {

            String vuePageUrl = mWebAddress + "#/generatePdfTest?pk_notification=" + cpk_notification + "&pk_emgency=" + cpk_emgency;
            driver.get(vuePageUrl);

            // 智能等待:直到页面设置true
            wait.until(ExpectedConditions.attributeToBe(
                    By.tagName("body"), "data-pdf-ready", "true"
            ));

            PrintOptions printOptions = new PrintOptions();
            printOptions.setBackground(true);
            printOptions.setPageRanges("1-5");

            // 替换原PDF字节处理代码
            Pdf pdf = ((PrintsPage) driver).print(printOptions);
            String base64Pdf = pdf.getContent(); // 获取Base64编码的PDF内容
            byte[] pdfBytes = Base64.getDecoder().decode(base64Pdf); // 解码为原始二进制

            Files.write(Paths.get(cPath), pdfBytes);
            log.info("调用Web端生成PDF文件成功: " + cPath);
            return true;
        } catch (Exception e) {
            log.error("获取Web端PDF文件失败:{}", e.getMessage(), e);
            return false;
        } finally {
            try {
                driver.quit();
            } catch (Exception ignore) {
            }
        }
    }
}

五、前端代码

前端vue仅供测试使用页面,具体业务使用需要进行美化和数据填充

在路由配置文件增加如下配置,实现路由和文件的绑定

    {
      path: '/generatePdfTest',
      name: 'GeneratePDFTest',
      component: (resolve) =>
        require(['@/components/notificationRecord/MedicalNotificationPdf'], resolve),
    }

具体pdf生成页面代码如下

<template>
  <div class="pdf-container">
    <h1>{{ title }}</h1>
    <div v-for="item in items" :key="item.id" class="item">
      <p><strong>{{ item.label }}:</strong> {{ item.value }}</p>
    </div>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        title: '测试通知记录书',
        items: []
      }
    },
    mounted() {
      try {
        // 检查路由是否可用(避免this.$route未定义的错误)
        if (!this.$route) {
          throw new Error("Vue Router未正确配置");
        }
        const recordId = this.$route.query.id || 'default';

        // 模拟数据加载
        setTimeout(() => {
          this.items = [
            { id: 1, label: '患者姓名', value: '张三' },
            { id: 2, label: '病历号', value: recordId },
            { id: 3, label: '诊断结果', value: 'stemi' },
            { id: 4, label: '诊断日期', value: '2025-08-12' },
            { id: 5, label: '诊断医生', value: '李四' }
          ];

          // 确认body元素存在后再设置属性
          if (document.body) {
            document.body.setAttribute('data-pdf-ready', 'true');
            console.log("PDF渲染标记已设置"); // 用于浏览器控制台调试
          } else {
            console.error("body元素不存在,无法设置标记");
          }
        }, 500);
      } catch (error) {
        console.error("组件加载错误:", error);
      }
    }
  }
</script>

<style scoped>
  /* 样式保持不变 */
  .pdf-container {
    width: 210mm;
    margin: 0 auto;
    padding: 20px;
    font-family: "SimSun";
  }
  .item {
    margin: 10px 0;
  }
</style>

六、最终效果

页面查看网页PDF

后端调用生成的PDF      

七、总结

该功能仅作为“曲线救国”方案,实际业务场景需要尽可能预想到该流程提前设计交互思路,供大家参考学习哈。

到此这篇关于Java调用Vue前端页面生成PDF文件的文章就介绍到这了,更多相关Java调用Vue前端生成PDF文件内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • spring声明式事务 @Transactional 不回滚的多种情况以及解决方案

    spring声明式事务 @Transactional 不回滚的多种情况以及解决方案

    本文主要介绍了spring声明式事务 @Transactional 不回滚的多种情况以及解决方案,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • 详解Java中的时区类TimeZone的用法

    详解Java中的时区类TimeZone的用法

    TimeZone可以用来获取或者规定时区,也可以用来计算时差,这里我们就来详解Java中的时区类TimeZone的用法,特别要注意下面所提到的TimeZone相关的时间校准问题.
    2016-06-06
  • 工厂方法在Spring框架中的运用

    工厂方法在Spring框架中的运用

    这篇文章介绍了工厂方法在Spring框架中的运用,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-10-10
  • Java 详细讲解用堆解决Top-k问题

    Java 详细讲解用堆解决Top-k问题

    TopK问题即在N个数中找出最大的前K个,这篇文章将详细讲解如何利用小根堆的方法解决TopK问题,文中代码具有一定参考价值,快跟随小编一起学习一下吧
    2022-04-04
  • 利用Spring boot+LogBack+MDC实现链路追踪

    利用Spring boot+LogBack+MDC实现链路追踪

    这篇文章主要介绍了利用Spring boot+LogBack+MDC实现链路追踪,MDC 可以看成是一个与当前线程绑定的哈希表,可以往其中添加键值对,下文详细介绍需要的小伙伴可以参考一下
    2022-04-04
  • 解决spring-boot 打成jar包后 启动时指定参数无效的问题

    解决spring-boot 打成jar包后 启动时指定参数无效的问题

    这篇文章主要介绍了解决spring-boot 打成jar包后 启动时指定参数无效的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • 详解JAVA后端实现统一扫码支付:微信篇

    详解JAVA后端实现统一扫码支付:微信篇

    本篇文章主要介绍了详解JAVA后端实现统一扫码支付:微信篇,这里整理了详细的代码,有需要的小伙伴可以参考下。
    2017-01-01
  • 基于java的opencv开发过程详解

    基于java的opencv开发过程详解

    这篇文章主要介绍了基于java的opencv开发过程详解,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04
  • 基于SpringBoot实现抽奖活动的四种策略

    基于SpringBoot实现抽奖活动的四种策略

    抽奖活动是产品运营中常见的用户激励和互动手段,通过随机性和奖励刺激用户参与度,提升用户活跃度和留存率,在技术实现上,抽奖系统涉及到随机算法、奖品分配、防作弊机制等多方面内容,本文将介绍基于SpringBoot实现抽奖活动的5种策略,需要的朋友可以参考下
    2025-06-06
  • Java web实现购物车案例

    Java web实现购物车案例

    这篇文章主要为大家详细介绍了Java web实现购物车案例,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08

最新评论