探索技术新边界:让 HTML 电子凭证与二维码、PDF 完美融合

朋友们!在数字化浪潮滚滚向前的今天,电子凭证的应用越来越广泛。咱做开发的,经常会碰到这样的需求:要在 HTML 电子凭证模版的指定位置贴上二维码,然后把它生成 PDF 电子凭证文档。这事儿听起来复杂,但只要找对方法,其实也不难。今天,我就带大家一起探索一下怎么用 Java 实现这个功能。

前期准备:依赖先行

咱做开发,依赖库就像是咱的武器库,选对了武器,战斗起来才能得心应手。在这个项目里,我们需要用到几个强大的开源库。如果你用 Maven 管理项目,在 pom.xml 里加上下面这些依赖:

<dependencies>
    <!-- ZXing 用于生成二维码 -->
    <dependency>
        <groupId>com.google.zxing</groupId>
        <artifactId>core</artifactId>
        <version>3.4.1</version>
    </dependency>
    <dependency>
        <groupId>com.google.zxing</groupId>
        <artifactId>javase</artifactId>
        <version>3.4.1</version>
    </dependency>
    <!-- Thymeleaf 用于处理 HTML 模板 -->
    <dependency>
        <groupId>org.thymeleaf</groupId>
        <artifactId>thymeleaf</artifactId>
        <version>3.1.1.RELEASE</version>
    </dependency>
    <!-- Flying Saucer 用于将 HTML 转换为 PDF -->
    <dependency>
        <groupId>org.xhtmlrenderer</groupId>
        <artifactId>flying-saucer-pdf</artifactId>
        <version>9.1.22</version>
    </dependency>
</dependencies>

这些依赖就像是我们的得力助手,有了它们,后面的开发工作就能顺利开展。

第一步:生成二维码

二维码在如今的数字化生活中无处不在,它就像是一把钥匙,能快速打开信息的大门。我们用 ZXing 库来生成二维码,代码如下:

 
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

public class QRCodeGenerator {
    public static String generateQRCodeBase64(String text, int width, int height) throws WriterException, IOException {
        QRCodeWriter qrCodeWriter = new QRCodeWriter();
        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        BitMatrix bitMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, width, height, hints);
        BufferedImage qrCodeImage = MatrixToImageWriter.toBufferedImage(bitMatrix);

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ImageIO.write(qrCodeImage, "png", byteArrayOutputStream);
        byte[] imageBytes = byteArrayOutputStream.toByteArray();
        return Base64.getEncoder().encodeToString(imageBytes);
    }
}

这里我们把生成的二维码转换为 Base64 编码的字符串,方便后面插入到 HTML 模板中。

第二步:创建 HTML 模板

HTML 模板就像是我们电子凭证的“骨架”,它规定了整个凭证的结构和样式。我们创建一个 voucher_template.html 文件,在需要插入二维码的地方留个占位符,就像这样:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>电子凭证</title>
</head>
<body>
    <h1>电子凭证</h1>
    <p>以下是二维码信息:</p>
    <img th:src="'data:image/png;base64,' + ${qrCodeBase64}" alt="QR Code">
</body>
</html>

这个占位符就像是一个“坑”,等着我们把生成的二维码“填”进去。

第三步:处理 HTML 模板并插入二维码

有了模板和二维码,接下来就是把它们结合起来。我们用 Thymeleaf 库来处理 HTML 模板,把二维码的 Base64 编码字符串插入到占位符的位置。代码如下:

import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class HtmlTemplateProcessor {
    public static String processTemplate(String templateName, Map<String, Object> variables) {
        ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
        templateResolver.setTemplateMode(TemplateMode.HTML);
        templateResolver.setCharacterEncoding("UTF-8");

        TemplateEngine templateEngine = new TemplateEngine();
        templateEngine.setTemplateResolver(templateResolver);

        Context context = new Context();
        context.setVariables(variables);

        return templateEngine.process(templateName, context);
    }
}

通过这个方法,我们就能把二维码“贴”到 HTML 模板的指定位置。

第四步:将 HTML 转换为 PDF

最后一步,就是把处理好的 HTML 转换成 PDF 文件。我们用 Flying Saucer 库来完成这个任务,代码如下:

 
import org.xhtmlrenderer.pdf.ITextRenderer;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class HtmlToPdfConverter {
    public static void convertHtmlToPdf(String htmlContent, String outputPath) throws IOException {
        try (OutputStream outputStream = new FileOutputStream(outputPath)) {
            ITextRenderer renderer = new ITextRenderer();
            renderer.setDocumentFromString(htmlContent);
            renderer.layout();
            renderer.createPDF(outputStream);
        }
    }
}

这样,我们就把 HTML 电子凭证转换成了 PDF 电子凭证文档。

主程序调用示例

下面是一个完整的主程序调用示例,把上面的步骤串起来:

 
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import com.google.zxing.WriterException;

public class Main {
    public static void main(String[] args) {
        try {
            // 要生成二维码的内容
            String qrCodeContent = "https://www.example.com";
            // 生成二维码的 Base64 编码
            String qrCodeBase64 = QRCodeGenerator.generateQRCodeBase64(qrCodeContent, 200, 200);

            // 准备模板变量
            Map<String, Object> variables = new HashMap<>();
            variables.put("qrCodeBase64", qrCodeBase64);

            // 处理 HTML 模板
            String processedHtml = HtmlTemplateProcessor.processTemplate("voucher_template.html", variables);

            // 生成的 PDF 文件输出路径
            String pdfOutputPath = "path/to/your/output.pdf";

            // 将 HTML 转换为 PDF
            HtmlToPdfConverter.convertHtmlToPdf(processedHtml, pdfOutputPath);

            System.out.println("PDF 电子凭证文档生成成功!");
        } catch (WriterException | IOException e) {
            e.printStackTrace();
        }
    }
}

注意事项

在开发过程中,有几个地方需要注意。首先,要确保 voucher_template.html 文件放在类路径下,不然程序找不到模板文件可就麻烦了。其次,可以根据实际需求调整二维码的大小和 HTML 模板的样式,让电子凭证看起来更美观。另外,处理中文等非 ASCII 字符时,要保证字符编码设置正确,避免出现乱码的情况。

朋友们,技术的魅力就在于不断探索和创新。通过今天的分享,希望大家能掌握在 HTML 电子凭证模版指定位置贴上二维码,并生成 PDF 电子凭证文档的方法。让我们一起在技术的道路上勇往直前,创造更多的可能!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/968800.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Flappy Bird开发学习记录

概述 为了了解一下Unity的开发过程&#xff0c;或者说感受&#xff1f;先搞简单的练练手。 工具 Unity:2022.3.51f1c1 visual studio 2022 开发过程 项目基本设置 新建2d项目&#xff0c;游戏画面设置为1080*1920&#xff08;9&#xff1a;16&#xff09;。 图片素材设…

35~37.ppt

目录 35.张秘书-《会计行业中长期人才发展规划》 题目​ 解析 36.颐和园公园&#xff08;25张PPT) 题目​ 解析 37.颐和园公园&#xff08;22张PPT) 题目 解析 35.张秘书-《会计行业中长期人才发展规划》 题目 解析 插入自定义的幻灯片&#xff1a;新建幻灯片→重用…

19.4.6 读写数据库中的二进制数据

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 需要北风数据库的请留言自己的信箱。 北风数据库中&#xff0c;类别表的图片字段在【数据表视图】中显示为Bitmap Image&#xff1…

sqli-lab靶场学习(六)——Less18-22(User-Agent、Referer、Cookie注入)

前言 前面的关卡&#xff0c;都是直接在输入框或者浏览器的地址栏上做文章即可。但本文这几关&#xff0c;需要用工具拦截请求修改请求头部才行。 Less18&#xff08;User-Agent注入&#xff09; 本关的注入点在User-Agent。我们在用户名和密码框中输入admin/admin后&#xf…

uniapp 使用 鸿蒙开源字体

uniapp vue3 使用 鸿蒙开源字体 我的需求是全局使用鸿蒙字体。 所以&#xff1a; 0. 首先下载鸿蒙字体&#xff1a; 鸿蒙资源 下载后解压&#xff0c;发现里面有几个文件夹&#xff1a; 字体名称说明Sans默认的鸿蒙字体&#xff0c;支持基本的多语言字符&#xff08;包括字…

【ESP32指向鼠标】——icm20948与esp32通信

【ESP32指向鼠标】——icm20948与esp32通信 ICM-20948介绍 ICM-20948 是一款由 InvenSense&#xff08;现为 TDK 的一部分&#xff09;生产的 9 轴传感器集成电路。它结合了 陀螺仪、加速度计和磁力计。 内置了 DMP&#xff08;Digital Motion Processor&#xff09;即负责执…

机器学习(李宏毅)——BERT

一、前言 本文章作为学习2023年《李宏毅机器学习课程》的笔记&#xff0c;感谢台湾大学李宏毅教授的课程&#xff0c;respect&#xff01;&#xff01;&#xff01; 读这篇文章必须先了解self-attention、Transformer&#xff0c;可参阅我其他文章。 二、大纲 BERT简介self-…

NO.12十六届蓝桥杯备战|关系操作符|操作符连用|浮点数比较|练习2道(C++)

关系操作符 关系操作符介绍 ⽤于⽐较的表达式&#xff0c;称为“关系表达式”&#xff08;relational expression&#xff09;&#xff0c;⾥⾯使⽤的运算符就称为“关 系运算符”&#xff08;relational operator&#xff09;&#xff0c;主要有下⾯6个。 运算符描述>⼤…

JVM组成

JVM是什么&#xff1f; JVM&#xff08;Java Virtual Machine&#xff09;&#xff1a;Java程序的运行环境(java二进制字节码的运行环境) 好处&#xff1a; 1.一次编写&#xff0c;到处运行 Java代码是如何做到一次编写&#xff0c;到处运行&#xff1f; 计算机的最底层是计…

不小心删除服务[null]后,git bash出现错误

不小心删除服务[null]后&#xff0c;git bash出现错误&#xff0c;如何解决&#xff1f; 错误描述&#xff1a;打开 git bash、msys2都会出现错误「bash: /dev/null: No such device or address」 问题定位&#xff1a; 1.使用搜索引擎搜索「bash: /dev/null: No such device o…

130,[1] 攻防世界 very_easy_sql

进入靶场 典型SQL注入页面 先查看源码 访问 试试http://127.0.0.1/ 还尝试了其他都是nonono 回归第一个登录页面 提交的内容不在url处显示&#xff0c;反而第二个url页面会在url处显示 明白第一个页面是通过post方式提交&#xff0c;反正没得到什么信息&#xff0c;去抓…

Android10 音频参数导出合并

A10 设备录音时底噪过大&#xff0c;让音频同事校准了下&#xff0c;然后把校准好的参数需要导出来&#xff0c;集成到项目中&#xff0c;然后出包&#xff0c;导出方式在此记录 设备安装debug系统版本调试好后&#xff0c; adb root adb remount adb shell 进入设备目录 导…

django中间件,中间件给下面传值

1、新建middleware.py文件 # myapp/middleware.py import time from django.http import HttpRequest import json from django.http import JsonResponse import urllib.parse from django.core.cache import cache from comm.Db import Db class RequestTimeMiddleware:def …

24电子信息类研究生复试面试问题汇总 电子信息类专业知识问题最全!电子信息复试全流程攻略 电子信息考研复试真题汇总

你是不是在为电子信息考研复试焦虑&#xff1f;害怕被老师问到刁钻问题、担心专业面答不上来&#xff1f;别慌&#xff01;作为复试面试92分逆袭上岸的学姐&#xff0c;今天手把手教你拆解电子信息类复试通关密码&#xff01;看完这篇&#xff0c;让你面试现场直接开大&#xf…

LVDS接口总结--(1)LVDS硬件电路接口

1.LVDS差分信号电路原理 LVDS指的是低压差分信号&#xff0c;是一种电平标准。 差分信号在串行通信中有着非常广泛的应用&#xff0c;典型应用有PCIE中的gen1&#xff0c;gen2&#xff0c;gen3&#xff0c;gen4&#xff0c;gen5&#xff0c;SATA接口&#xff0c;USB接口等。 …

【STM32】HAL库Host MSC读写外部U盘及FatFS文件系统的USB Disk模式

【STM32】HAL库Host MSC读写外部U盘及FatFS文件系统的USB Disk模式 在先前 分别介绍了FatFS文件系统和USB虚拟U盘MSC配置 前者通过MCU读写Flash建立文件系统 后者通过MSC连接电脑使其能够被操作 这两者可以合起来 就能够实现同时在MCU、USB中操作Flash的文件系统 【STM32】通过…

第四期书生大模型实战营-第5关-L2G5000

1 Web 版茴香豆 助教说这趴先跳过&#xff0c;那我就跳过 2 茴香豆本地标准版搭建 2.1 环境搭建 2.2 安装茴香豆 2.3 知识库创建 2.4 测试知识助手 2.4.1 命令行运行 2.4.2 Gradio UI 界面测试 确认一下是否正常 完美。 至于选做&#xff0c;我这么懒&#xff0c;怎么可能…

Elastic Cloud Serverless 现已在 Microsoft Azure 上提供技术预览版

作者&#xff1a;来自 Elastic Yuvi Gupta Elastic Cloud Serverless 提供了启动和扩展安全性、可观察性和搜索解决方案的最快方法 — 无需管理基础设施。 今天&#xff0c;我们很高兴地宣布 Microsoft Azure 上的 Elastic Cloud Serverless 技术预览版现已在美国东部地区推出。…

go语言简单快速的按顺序遍历kv结构(map)

文章目录 需求描述用map实现按照map的key排序用二维切片实现用结构体实现 需求描述 在go语言中&#xff0c;如果需要对map遍历&#xff0c;每次输出的顺序是不固定的&#xff0c;可以考虑存储为二维切片或结构体。 假设现在需要在页面的下拉菜单中展示一些基础的选项&#xff…

TDengine 产品由哪些组件构成

目 录 背景产品生态taosdtaosctaosAdaptertaosKeepertaosExplorertaosXtaosX Agent应用程序或第三方工具 背景 了解一个产品&#xff0c;最好从了解产品包括哪些内容开始&#xff0c;我这里整理了一份儿 TDegnine 产品包括有哪些组件&#xff0c;每个组件作用是什么的说明&a…