将HTML转换为PDF:使用Spire.Doc的详细指南(一) 试用版

目录

引言

1. 为什么选择 Spire.Doc?

1.1 主要特点

1.2 适用场景

2. 准备工作

2.1 引入 Spire.Doc 依赖

2.2 禁用 SSL 证书验证

3. 实现功能

3.1 主类结构

3.2 代码解析

4. 处理图像

5. 性能优化

5.1 异步下载图像

示例代码

5.2 批量处理优化

示例代码

6. 错误处理与日志管理

6.1 错误处理

示例代码

6.2 日志管理

示例代码

7. 总结


引言

在现代软件开发中,生成 PDF 文档的需求日益增长,尤其是在金融、教育、医疗等行业。PDF 格式以其固定的外观和出色的可移植性受到广泛欢迎。本文将详细介绍如何使用 Spire.Doc 库将 HTML 文件转换为 PDF 文件。本文包括完整代码示例、相关依赖管理,以及对过程中的关键概念的深入探讨。

1. 为什么选择 Spire.Doc?

Spire.Doc 是一款强大的 .NET 文档处理库,支持多种文档格式的创建、编辑和转换。使用 Spire.Doc 可以简化 HTML 转 PDF 的过程,支持复杂的 HTML 内容,包括图片、样式和链接等。

1.1 主要特点

  • 无依赖:Spire.Doc 不依赖于 Microsoft Office,可以直接在服务器端运行。
  • 高性能:能够快速处理和转换文档。
  • 易于使用:提供友好的 API 接口,便于开发者快速上手。

1.2 适用场景

  • 生成报表:将动态生成的 HTML 报告转换为 PDF。
  • 文档归档:将在线文档归档为 PDF,便于存储和分发。
  • 邮件发送:将用户生成的内容转换为 PDF,并通过邮件发送。

2. 准备工作

在开始之前,请确保你的开发环境中已配置 Java,并安装了 IDE(如 IntelliJ IDEA 或 Eclipse)。接下来,需要在项目中添加 Spire.Doc 依赖。

2.1 引入 Spire.Doc 依赖

在你的项目中,可以通过 Maven 引入 Spire.Doc,如下所示:

<dependency>  <groupId>e-iceblue</groupId>  <artifactId>spire.doc.free</artifactId>  <version>5.2.0</version>  
</dependency>

2.2 禁用 SSL 证书验证

在处理一些需要 HTTPS 连接的 HTML 内容时,可能会遇到 SSL 证书验证问题。为了避免这些问题,可以临时禁用 SSL 验证。下面是一个实现示例:

public static void disableSSLVerification() {  try {  TrustManager[] trustAllCerts = new TrustManager[]{  new X509TrustManager() {  public X509Certificate[] getAcceptedIssuers() {  return null;  }  public void checkClientTrusted(X509Certificate[] certs, String authType) {  }  public void checkServerTrusted(X509Certificate[] certs, String authType) {  }  }  };  SSLContext sc = SSLContext.getInstance("SSL");  sc.init(null, trustAllCerts, new java.security.SecureRandom());  HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());  HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> true);  } catch (Exception e) {  e.printStackTrace();  }  
}

3. 实现功能

接下来,我们将实现一个完整的 Java 类,通过读取 HTML 文件,将其转换为 PDF。在这个过程中,我们将重点介绍文件读取、HTML 内容处理和 PDF 文件生成的步骤。

3.1 主类结构

以下是我们的主类 DocToPdfConverter 的结构,这里包含了所有必要的方法:

package com.dahua.saas.illegalpunish.controller;  import com.spire.doc.Document;  
import com.spire.doc.FileFormat;  
import com.spire.doc.Section;  import javax.net.ssl.*;  
import java.security.cert.X509Certificate;  
import java.io.BufferedReader;  
import java.io.FileReader;  
import java.io.IOException;  
import java.io.InputStream;  
import java.net.HttpURLConnection;  
import java.net.URL;  
import java.util.regex.Matcher;  
import java.util.regex.Pattern;  public class DocToPdfConverter {  public static void main(String[] args) throws IOException {  disableSSLVerification();  String inputHtml = "C:\\cloud\\dahua\\VIASBIllegalPunish\\file\\1912202400018.doc";  Document doc = new Document();  Section sec = doc.addSection();  String htmlText = readTextFromFile(inputHtml);  sec.addParagraph().appendHTML(replaceImagesWithHighRes(htmlText));  doc.saveToFile("C:\\cloud\\dahua\\VIASBIllegalPunish\\file\\1912202400018.pdf", FileFormat.PDF);  doc.dispose();  }  // 读取文本文件内容  public static String readTextFromFile(String fileName) throws IOException {  StringBuilder sb = new StringBuilder();  BufferedReader br = new BufferedReader(new FileReader(fileName));  String content;  while ((content = br.readLine()) != null) {  sb.append(content);  sb.append(System.lineSeparator());  }  return sb.toString();  }  // 替换 HTML 文本中的图片链接为高分辨率图像  public static String replaceImagesWithHighRes(String html) {  String imageUrlPattern = "https?://[^\\s\"'<>]+";  Pattern pattern = Pattern.compile(imageUrlPattern);  Matcher matcher = pattern.matcher(html);  StringBuffer resultHtml = new StringBuffer();  while (matcher.find()) {  String imageUrl = matcher.group();  String highResImage = downloadImage(imageUrl);  matcher.appendReplacement(resultHtml, highResImage);  }  matcher.appendTail(resultHtml);  return resultHtml.toString();   }  // 下载图片,返回高分辨率的图像数据  public static String downloadImage(String imageUrl) {  try {  URL url = new URL(imageUrl);  HttpURLConnection connection = (HttpURLConnection) url.openConnection();  connection.setDoInput(true);  connection.connect();  InputStream input = connection.getInputStream();  // 这里可以实现将输入流转换为适合插入 PDF 的格式  return imageUrl; // 现在只是返回原始 URL  } catch (IOException e) {  e.printStackTrace();  return imageUrl;   }  }  
}

3.2 代码解析

  • 禁用 SSL 验证:通过调用 disableSSLVerification() 方法来忽略 SSL 证书验证,以便可以访问 HTTP 和 HTTPS 内容。

  • 读取 HTML 文件:使用 readTextFromFile() 方法读取指定路径下的 HTML 文件。这个方法使用 BufferedReader 逐行读取,最终返回一个完整的 HTML 内容字符串。

  • 处理图片链接:在 replaceImagesWithHighRes() 方法中,首先通过正则表达式查找所有的图片链接,然后下载高分辨率的图片。在这里,具体的下载逻辑需要根据实际情况实现,例如可以选择将图像转换为 Base64 格式,并替换 HTML 内容中的 src 属性以达到嵌入图像的效果。

  • 生成 PDF:使用 Spire.Doc 库创建一个新的 Document 对象,并添加一个 Section,然后通过 appendHTML() 方法将处理后的 HTML 内容添加到文档中。最后,调用 saveToFile() 方法将文档保存为 PDF 格式的文件。

4. 处理图像

在本示例中,downloadImage 方法返回的是原始的图像 URL。在实际应用中,您可能需要将下载的图片以适当的格式嵌入 PDF,例如将其转换为 Base64 字符串。下面是一个简单的实现示例:

public static String downloadImage(String imageUrl) {  try {  URL url = new URL(imageUrl);  HttpURLConnection connection = (HttpURLConnection) url.openConnection();  connection.setDoInput(true);  connection.connect();  InputStream input = connection.getInputStream();  // Convert InputStream to byte array  byte[] imageBytes = input.readAllBytes();  String base64Image = Base64.getEncoder().encodeToString(imageBytes);  return "data:image/png;base64," + base64Image; // Assuming image is PNG  } catch (IOException e) {  e.printStackTrace();  return imageUrl;   }  
}

5. 性能优化

在处理大量图像时,批量处理或异步下载可以显著提高程序的性能和响应速度。以下是一些优化建议和具体实现策略。

5.1 异步下载图像

使用 Java 的并发 API,可以实现异步下载图像。这意味着在处理 HTML 的同时,可以在后台下载图像,不阻塞主线程。

示例代码

使用 CompletableFuture 来实现异步下载图像的能力:

import java.util.concurrent.CompletableFuture;  public static CompletableFuture<String> downloadImageAsync(String imageUrl) {  return CompletableFuture.supplyAsync(() -> {  try {  URL url = new URL(imageUrl);  HttpURLConnection connection = (HttpURLConnection) url.openConnection();  connection.setDoInput(true);  connection.connect();  InputStream input = connection.getInputStream();  byte[] imageBytes = input.readAllBytes();  String base64Image = Base64.getEncoder().encodeToString(imageBytes);  return "data:image/png;base64," + base64Image; // 假设图像为 PNG  } catch (IOException e) {  e.printStackTrace();  return imageUrl;   }  });  
}

然后在 replaceImagesWithHighRes() 方法中,使用 Java 的流处理来启动异步下载:

public static String replaceImagesWithHighRes(String html) {  String imageUrlPattern = "https?://[^\\s\"'<>]+";  Pattern pattern = Pattern.compile(imageUrlPattern);  Matcher matcher = pattern.matcher(html);  List<CompletableFuture<String>> futures = new ArrayList<>();  StringBuffer resultHtml = new StringBuffer();  while (matcher.find()) {  String imageUrl = matcher.group();  CompletableFuture<String> future = downloadImageAsync(imageUrl);  futures.add(future);  matcher.appendReplacement(resultHtml, ""); // 先将占位符放入结果 HTML  }  matcher.appendTail(resultHtml);  // 等待所有图像下载完成  CompletableFuture<Void> allOf = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));  allOf.join();  // 等待所有 CompletableFuture 完成  // 用下载后的图像替换  for (int i = 0; i < futures.size(); i++) {  try {  String downloadedImage = futures.get(i).get(); // 获取下载过的图像  String placeholder = ""; // 这里可以根据需要生成占位符  // 将占位符替换为实际的图像  resultHtml = new StringBuffer(resultHtml.toString().replaceFirst(Pattern.quote(placeholder), downloadedImage));   } catch (Exception e) {  e.printStackTrace();  }  }  return resultHtml.toString();   
}

通过以上方式,您可以实现图像的异步下载,从而提升程序的性能,特别是在处理大量数据时。

5.2 批量处理优化

如果 HTML 文件中包含大量的图像,您还可以采取以下措施进行批量处理:

  • 限制并发量:在实际运行中,尤其是在网络条件不确定的情况下,限制并发请求的数量可以避免请求过载和资源竞争。可以使用 Java 的信号灯(Semaphore)来控制并发。
示例代码
import java.util.concurrent.Semaphore;  private static final Semaphore semaphore = new Semaphore(5); // 最多允许 5 个并发下载  public static CompletableFuture<String> downloadImageAsync(String imageUrl) {  return CompletableFuture.supplyAsync(() -> {  try {  semaphore.acquire(); // 获取信号量  try {  // 文章前面提到的下载逻辑  URL url = new URL(imageUrl);  HttpURLConnection connection = (HttpURLConnection) url.openConnection();  connection.setDoInput(true);  connection.connect();  InputStream input = connection.getInputStream();  byte[] imageBytes = input.readAllBytes();  String base64Image = Base64.getEncoder().encodeToString(imageBytes);  return "data:image/png;base64," + base64Image;  } finally {  semaphore.release(); // 释放信号量  }  } catch (IOException e) {  e.printStackTrace();  return imageUrl;   }  });  
}

通过这种方式,您可以控制并发量,从而降低服务器负载和提高下载成功率。

6. 错误处理与日志管理

在处理网络请求和文件操作时,错误处理至关重要。应确保在项目中实现有效的日志记录和错误处理机制。

6.1 错误处理

确保任何网络请求、文件读取和转换操作都能妥善处理异常情况。以下是一些建议:

  • 捕获并记录异常:应在每个网络请求和文件操作中捕获异常并记录详细信息,以便后期调试。
  • 使用重试机制:对于短暂的网络问题,可以使用重试逻辑重新尝试下载图像。
示例代码
public static String downloadImageWithRetry(String imageUrl, int retryCount) {  for (int i = 0; i < retryCount; i++) {  try {  return downloadImage(imageUrl); // 使用之前定义的下载逻辑  } catch (IOException e) {  if (i == retryCount - 1) {  e.printStackTrace(); // 记录最终失败的情况  }  }  }  return imageUrl; // 默认返回原始的 URL  
}

6.2 日志管理

可以使用日志框架(如 SLF4J、Log4j)来进行日志管理。将日志记录在适当的级别(例如 INFO、WARN、ERROR),可以帮助开发人员在出现问题时快速定位。

示例代码
import org.slf4j.Logger;  
import org.slf4j.LoggerFactory;  public class DocToPdfConverter {  private static final Logger logger = LoggerFactory.getLogger(DocToPdfConverter.class);  public static void main(String[] args) {  try {  // 主逻辑  } catch (Exception e) {  logger.error("Error occurred during PDF conversion", e);  }  }  
}

7. 总结

本文介绍了如何使用 Spire.Doc 将 HTML 文件转换为 PDF 的详细过程。我们探讨了图像处理方法,包括同步和异步下载,并提供了实用的性能优化建议。此外,我们还强调了错误处理和日志管理的重要性,以增强代码的健壮性。

应用这些技术,您将能够高效地处理 HTML 文档,转化为高质量的 PDF 格式,满足现代软件开发中的各种需求。如需进一步信息或帮助,欢迎随时联系我解答您的疑问。希望本文能够为您的开发工作提供实用的参考和指导!

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【快速上手】linux环境下Neo4j的安装与使用

一、neo4j简介 neo4j是一个非关系型图形数据库&#xff0c;非常适合处理具有复杂关系的数据集 存储方式&#xff1a;图形化存储 特点&#xff1a;将结构化数据存储在图上而不是表&#xff08;比如&#xff1a;MySQL数据库存储在表中&#xff09;中 neo4j也可以看作是一个高…

【看海的算法日记✨优选篇✨】第二回:流动之窗,探索算法的优雅之道

&#x1f308; 个人主页&#xff1a;谁在夜里看海. &#x1f525; 个人专栏&#xff1a;《C系列》《Linux系列》《算法系列》 ⛰️ 道阻且长&#xff0c;行则将至 目录 一、算法思想 双指针 滑动窗口 二、具体运用 1.⻓度最⼩的⼦数组 算法思路 算法流程 代码 2.最⼤…

Tool之Excalidraw:Excalidraw(开源的虚拟手绘风格白板)的简介、安装和使用方法、艾米莉应用之详细攻略

Tool之Excalidraw&#xff1a;Excalidraw(开源的虚拟手绘风格白板)的简介、安装和使用方法、艾米莉应用之详细攻略 目录 Excalidraw 简介 1、Excalidraw 的主要特点&#xff1a; Excalidraw 安装和使用方法 1、Excalidraw的安装 T1、使用 npm 安装&#xff1a; T2、使用 …

设计模式之【观察者模式】

观察者模式&#xff1a; 应用于发布-订阅消息模型中&#xff0c;订阅者订阅一个主题后&#xff0c;当有新消息到达时&#xff0c;所有订阅者都会收到通知。 主要关注的是对象之间的通信。是一种对象之间的一对多关系&#xff0c;多个对象依赖于一个对象&#xff0c;当被依赖的…

页面无滚动条,里面div各自有滚动条

一、双滚动条左右布局 实现效果 实现代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>Doc…

(Z Shell)zsh: no matches found: ? 使用单引号包裹

文章目录 dgqdgqdeMac-mini ProductAuthentication % git commit -m "open-type"{{isCodeValid ? getPhoneNumber : none}}"" zsh: no matches found: ?git commit -m open-type"{{isCodeValid ? getPhoneNumber : none}}"你遇到的 zsh: no m…

鸿蒙元服务从0到上架【第二篇】

第一招&#xff1a;在AppGallery后台下载对应的证书等文件 AppGallery后台 新增发布证书&#xff0c;具体操作可查看申请发布证书 申请发布Profile证书 第二招&#xff1a;在IDE中填写 第三招&#xff1a;打包【⚠️发布上架的只能是Build App】 终端展示这一片绿&#xf…

网络安全概论——身份认证

一、身份证明 身份证明可分为以下两大类 身份验证——“你是否是你所声称的你&#xff1f;”身份识别——“我是否知道你是谁&#xff1f;” 身份证明系统设计的三要素&#xff1a; 安全设备的系统强度用户的可接受性系统的成本 实现身份证明的基本途径 所知&#xff1a;个…

【学习记录】浏览器指纹相关学习记录(指纹介绍、获取指纹、修改指纹、随机指纹保护隐私等)

用途 不需要用户登录&#xff0c;可以识别是同一个用户&#xff0c;用于反爬虫广告推送等一类的场景 指纹在线查询地址 http://www.fingerprintbrowser.com/ CreepJS 浏览器指纹在线检测网站:代理IP防关联伪装度查询工具 IP检测大师 【自动化】Python SeleniumUtil 工具 开…

redis数据转移

可能有时候因为硬件的原因我们我们需要更换服务器&#xff0c;如果更换服务器的话&#xff0c;那我们redis的数据该怎样转移呢&#xff0c;按照一下步骤即可完成redis数据的转移 1.进入redis客户端 2.使用 bgsave命令进行数据的备份&#xff0c;此命令完成后会在你的redis安装目…

【MySQL】数据库 Navicat 可视化工具与 MySQL 命令行基本操作

&#x1f4af; 欢迎光临清流君的博客小天地&#xff0c;这里是我分享技术与心得的温馨角落 &#x1f4af; &#x1f525; 个人主页:【清流君】&#x1f525; &#x1f4da; 系列专栏: 运动控制 | 决策规划 | 机器人数值优化 &#x1f4da; &#x1f31f;始终保持好奇心&…

腾讯云智能结构化OCR:以多模态大模型技术为核心,推动跨行业高效精准的文档处理与数据提取新时代

&#x1f3bc;个人主页&#xff1a;【Y小夜】 &#x1f60e;作者简介&#xff1a;一位双非学校的大三学生&#xff0c;编程爱好者&#xff0c; 专注于基础和实战分享&#xff0c;欢迎私信咨询&#xff01; &#x1f386;入门专栏&#xff1a;&#x1f387;【MySQL&#xff0…

登山第十六梯:深度恢复——解决机器人近视问题

文章目录 一 摘要 二 资源 三 内容 一 摘要 深度感知是基于 3D 视觉的机器人技术的一个重要问题。然而&#xff0c;现实世界的主动立体或 ToF 深度相机经常会产生嘈杂且深度不完整&#xff0c;从而成为机器人性能的瓶颈。在这项工作中&#xff0c;提出了 一个基于学习的立体…

Leetcode中最常用的Java API——util包

前言&#xff1a;在刷力扣的时候是核心代码模式&#xff0c;笔试的时候很可能是ACM模式&#xff0c;需要自己完成导包、定义和自行设计输出&#xff0c;所以一些常用的类和方法需要先导入相应的API包&#xff0c;java.util就是最常用到的包&#xff0c;因为它包含集合这个大框架…

JVM对象分配内存如何保证线程安全?

大家好&#xff0c;我是锋哥。今天分享关于【JVM对象分配内存如何保证线程安全&#xff1f;】面试题。希望对大家有帮助&#xff1b; JVM对象分配内存如何保证线程安全&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在JVM中&#xff0c;对象的内存分配…

前端使用 Konva 实现可视化设计器(20)- 性能优化、UI 美化

这一章主要分享一下使用 Konva 遇到的性能优化问题&#xff0c;并且介绍一下 UI 美化的思路。 至少有 2 位小伙伴积极反馈&#xff0c;发现本示例有明显的性能问题&#xff0c;一是内存溢出问题&#xff0c;二是卡顿的问题&#xff0c;在这里感谢大家的提醒。 请大家动动小手&a…

AIGC-------AI生成内容如何赋能AR和VR体验?

AI生成内容如何赋能AR和VR体验 引言 增强现实&#xff08;AR&#xff09;和虚拟现实&#xff08;VR&#xff09;技术近年来蓬勃发展&#xff0c;为用户提供了沉浸式的体验。这些技术已经广泛应用于游戏、教育、医疗、建筑等领域。然而&#xff0c;AR和VR体验的质量与内容的丰富…

VLM--CLIP作分类任务的损失函数

info_nce_loss 这个是clip作对比学习的损失函数 各个博客上都有详细介绍了&#xff0c;我这里就不赘述 def info_nce_loss(image_features, text_features,logit_scale,labels, temperature0.07):batch_size image_features.shape[0]image_features image_features / image…

【模型压缩】原理及实例

在移动智能终端品类越发多样的时代&#xff0c;为了让模型可以顺利部署在算力和存储空间都受限的移动终端&#xff0c;对模型进行压缩尤为重要。模型压缩&#xff08;model compression&#xff09;可以降低神经网络参数量&#xff0c;减少延迟时间&#xff0c;从而实现提高神经…

leetcode-128.最长连续序列-day14

为什么我感觉上述代码时间复杂度接近O(2n), 虽然有while循环&#xff0c;但是前面有个if判断&#xff0c;能进入while循环的也不多&#xff0c;while循环就相当于两个for循环&#xff0c;但不是嵌套类型的&#xff1a; 变量作用域问题&#xff1a;