.NET/C#下html转PDF,PDF加水印,PDF转图片

2023-11-13

一、添加OpenHtmlToPdf,iTextSharp,O2S.Components.PDFRender4NET引用

(1)OpenHtmlToPdf:是一个.NET库(开源的),用于将HTML文档呈现为PDF格式。

github地址:https://github.com/vilppu/OpenHtmlToPdf

(2)iTextSharp:是一个.NET下处理pdf文件的库,提供给pdf文件加水印的功能。

官网:https://itextpdf.com/en

(3)O2S.Components.PDFRender4NET:是一个.NET库,用于将PDF文档呈现为图片。

想要在C#中把html转成PDF,PDF转成图片,首先得要有个C#版的驱动。

通过网络下载或nuget安装,得到OpenHtmlToPdf、iTextSharp、O2S.Components.PDFRender4NET相关的dll,添加到项目中引用。

第一步:在项目中右键,选择管理NuGet程序包

第二步:搜索OpenHtmlToPdf、iTextSharp,选中安装

第三步:下载O2S.Components.PDFRender4NET.dll,在Nuget中没找到,只能自己找资源下载了

下载地址:https://download.csdn.net/download/u011301348/12442663

下载完成后添加dll引用到项目中

通过这三步,在项目中有OpenHtmlToPdf、iTextSharp、O2S.Components.PDFRender4NET的引用,表示添加成功

二、创建PDFTools工具类

/// <summary>
/// PDF工具
/// </summary>
public class PDFTools
{
        /// <summary>
        /// html转pdf
        /// </summary>
        /// <param name="html"></param>
        /// <param name="watermarkimg">水印图片</param>
        /// <returns></returns>
        public static string HtmlToPdf(string html, string watermarkimg)
        {
            var document = Pdf.From(html)
                .OfSize(PaperSize.A4)  //大小,这里选A4纸大小
                .WithGlobalSetting("margin.top", "0.4cm");  //设置全局样式

            //此属性的值在32位进程中为4,在64位进程中为8。
            if (IntPtr.Size == 4)
            {
                document = document.WithObjectSetting("load.zoomFactor", "1.5");
            }
            var result = document.Content();
            string filePath = "pdf/" + DateTime.Now.ToString("yyyyMMddHH") + "/";//路径
            if (!Directory.Exists(filePath))
            {
                Directory.CreateDirectory(AppDomain.CurrentDomain.BaseDirectory + filePath);//保存在当前项目跟路径下
            }
            string fileName = DateTime.Now.ToString("yyyyMMddHHmmssffffff") + ".pdf";
            //通过stream把html写入到pdf文件中
            FileStream fs = new FileStream(AppDomain.CurrentDomain.BaseDirectory + filePath + fileName, FileMode.Create, FileAccess.Write);
            fs.Write(result, 0, result.Length);
            fs.Close();
            //加水印
            string filewatermarkPath = filePath + DateTime.Now.ToString("yyyyMMddHHmmssffffff") + ".pdf";
            var res = PDFWatermark(AppDomain.CurrentDomain.BaseDirectory + filePath + fileName, AppDomain.CurrentDomain.BaseDirectory + filewatermarkPath, watermarkimg);
            if (res)
            {
                if (File.Exists(AppDomain.CurrentDomain.BaseDirectory + filePath + fileName))
                    File.Delete(AppDomain.CurrentDomain.BaseDirectory + filePath + fileName);
                return filewatermarkPath;
            }
            else
                return filePath + fileName;
        }

        /// <summary>
        /// PDF转化为图片
        /// </summary>
        /// <param name="filePath">文件路径</param>
        /// <param name="resolution">分辨率</param>
        /// <returns></returns>
        public static List<string> PDFToIMG(string filePath, float resolution)
        {
            string imgPath = "pdf/IMG/" + DateTime.Now.ToString("yyyyMMddHH") + "/";
            //如果文件夹不存在,则创建
            if (!Directory.Exists(imgPath))
            {
                Directory.CreateDirectory(AppDomain.CurrentDomain.BaseDirectory + imgPath);
            }
            PDFFile file = PDFFile.Open(filePath);
            int pageCount = file.PageCount;
            List<string> imgPathList = new List<string>();
            for (int i = 0; i < pageCount; i++)
            {
                string imgName = DateTime.Now.ToString("yyyyMMddHHmmssffffff") + ".jpg";
                Bitmap img = file.GetBWPageImage(i, resolution);
                img.Save(AppDomain.CurrentDomain.BaseDirectory + imgPath + imgName, System.Drawing.Imaging.ImageFormat.Jpeg);
                imgPathList.Add(imgPath + imgName);
            }
            return imgPathList;
        }

        /// <summary>
        /// pdf加水印
        /// </summary>
        /// <param name="inputfilepath">模板路径</param>
        /// <param name="outputfilepath">导出水印背景后的PDF</param>
        /// <param name="ModelPicName">水印图片</param>
        /// <returns></returns>
        public static bool PDFWatermark(string inputfilepath, string outputfilepath, string ModelPicName)
        {
            PdfReader pdfReader = null;
            PdfStamper pdfStamper = null;
            try
            {
                pdfReader = new PdfReader(inputfilepath);
                pdfStamper = new PdfStamper(pdfReader, new FileStream(outputfilepath, FileMode.Create));
                PdfGState gs = new PdfGState();
                gs.FillOpacity = 0.4f;//透明度

                iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(ModelPicName);

                int numberOfPages = pdfReader.NumberOfPages;

                //每一页加2个水印,也可以设置某一页加水印
                for (int i = 1; i <= numberOfPages; i++)
                {
                    PdfContentByte waterMarkContent = pdfStamper.GetOverContent(i);//内容上层加水印
                    //PdfContentByte waterMarkContent = pdfStamper.GetUnderContent(i);//内容下层加水印
                    waterMarkContent.SetGState(gs);
                    image.SetAbsolutePosition(20, 100);//水印定位坐标
                    waterMarkContent.AddImage(image);
                    image.SetAbsolutePosition(20, 300);
                    waterMarkContent.AddImage(image);
                }
                //一定要2个循环才会在每一个加上水印,咱也不知道为啥,反正是试了好久试出来的
                for (int i = 1; i <= numberOfPages; i++)
                {
                    PdfContentByte waterMarkContent = pdfStamper.GetOverContent(i);//内容上层加水印
                    //PdfContentByte waterMarkContent = pdfStamper.GetUnderContent(i);//内容下层加水印
                    waterMarkContent.SetGState(gs);
                    image.SetAbsolutePosition(20, 100);
                    waterMarkContent.AddImage(image);
                    image.SetAbsolutePosition(20, 300);
                    waterMarkContent.AddImage(image);
                }
                return true;
            }
            catch (Exception ex)
            {
                ex.Message.Trim();
                return false;
            }
            finally
            {
                if (pdfStamper != null)
                    pdfStamper.Close();

                if (pdfReader != null)
                    pdfReader.Close();
            }
        }
}

三、调用

在HomeController中添加一下方法。

1.定义组装html生成pdf文件,并给pdf加水印方法

public string CreatePdf()
{
            StringBuilder detail = new StringBuilder();
            detail.Append(@"<p><span style='FONT-FAMILY:宋体;BACKGROUND:white;COLOR:#333333'></span></p><p><span style='FONT-FAMILY:宋体;BACKGROUND:white;COLOR:#333333'>pdf商品</span></p>");
            detail.Append(@"<table style='WIDTH:280px' height='159' cellspacing='0' cellpadding='0' width='807' align='center' uetable='null' data-sort='sortDisabled'><tbody>");
            detail.Append("<tr class='firstRow'>");
            detail.Append("<td valign='top' width='47'><p><span style='FONT-SIZE:13px;FONT-FAMILY:宋体;BACKGROUND:white;COLOR:#333333'>序号</span></p></td>");
            detail.Append("<td valign ='top' width='83'><p style='TEXT-ALIGN:center'><span style='FONT-SIZE:13px;FONT-FAMILY:宋体;BACKGROUND:white;COLOR:#333333'>商品名称</span></p></td>");
            detail.Append("<td valign='top' width='132'><p style='TEXT-ALIGN:center'><span style='FONT-SIZE:13px;FONT-FAMILY:宋体;BACKGROUND:white;COLOR:#333333'>品牌</span></p ></td>");
            detail.Append("<td valign='top' width='75'><p style='TEXT-ALIGN:center'><span style='FONT-SIZE:13px;FONT-FAMILY:宋体;BACKGROUND:white;COLOR:#333333'>单位</span></span></p></td>");
            detail.Append("<td valign='top' width='50'><p style='TEXT-ALIGN:center'><span style='FONT-SIZE:13px;FONT-FAMILY:宋体;BACKGROUND:white;COLOR:#333333'>规格</span></p></td>");
            detail.Append("<td valign='top' width='66'><p style='TEXT-ALIGN:center'><span style='FONT-SIZE:13px;FONT-FAMILY:宋体;BACKGROUND:white;COLOR:#333333'>价格</span></p></td>");
            detail.Append("</tr>");
            for (int i = 1; i < 100; i++)
            {
                detail.Append("<tr>");
                detail.Append($"<td valign='top' width='47'>{i}</td>");
                detail.Append($"<td valign='top' width='83'>商品{i}</td>");
                detail.Append($"<td valign='top' width='83'>品牌{i}</td>");
                detail.Append($"<td valign='top' width='83'>单位{i}</td>");
                detail.Append($"<td valign='top' width='83'>规格{i}</td>");
                detail.Append($"<td valign='top' width='83'>价格{i}</td>");
                detail.Append("</tr>");
                i++;
            }
            detail.Append("</tbody></table>");
            //生成PDF
            string html = $"<!DOCTYPE html><html><head><meta charset='UTF-8'><title>pdf</title></head><body>{detail.ToString()}</body></html>";
            string pdfPath = PDFTools.HtmlToPdf(html, $"{AppDomain.CurrentDomain.BaseDirectory}/Images/wm.jpeg");
            return pdfPath;
}

2.在Index中调用。

public ActionResult Index()
{
            string pdfpath = CreatePdf();//生成pdf,加水印
            ViewBag.pdfpath = pdfpath;
            ViewBag.imgpath = PDFTools.PDFToIMG(AppDomain.CurrentDomain.BaseDirectory + pdfpath, 200);//pdf转图片
            return View();
}

3.查看结果

4.浏览器中打开pdf文件效果

5.转换成图片效果

四、代码下载地址

https://download.csdn.net/download/u011301348/12446794

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

.NET/C#下html转PDF,PDF加水印,PDF转图片 的相关文章

  • python文件开头两行#!/usr/bin/python和# -*- coding:utf-8 -*-解释以及Pycharm自动创建py文件头部信息

    我们常见到python文件的前两行都会写上如下两行代码 下面我分别解释这两条语句的意义 并介绍pycharm中自动生成py文件头部信息的方法 usr bin env python coding utf 8 或者 usr bin python
  • vs2019 中编译和使用 protobuf 库

    背景 protobuf 是一种跨平台的序列化结构数据的方法 可用于网络数据传输及存储 本文对使用 vs2019 编译 protobuf 库文件进行说明 相关代码及安装文件均来自官网下载 VS2019 编译 protobuf 生成 sln 工
  • 实时语音通讯技术的应用场景与挑战

    随着互联网和移动通信技术的快速发展 实时语音通讯技术已经成为人们日常生活和工作中不可或缺的一部分 实时语音通讯技术可以让人们通过网络进行实时语音通话 不受时间和地点的限制 带来了极大的便利和效率提升 本文将探讨实时语音通讯技术的应用场景和挑
  • Java并发之ThreadLocal源码分析(第二篇:添加元素)

    前言 两个与添加元素相关的方法 initialValue 用于初始化一个默认值 set 用于添加一个元素 set 方法分析 public void set T value Thread t Thread currentThread Thre
  • Pycharm运行unittest报错ModuleNotFoundError: No module named ‘pytest‘解决

    使用unittest未import pytest相关功能语句 在pycharm中右键run的时候报错 Traceback most recent call last File B Application pycharm PyCharm 20
  • FCK配置中文版(转自网络,未知来源)

    1 FCKConfig CustomConfigurationsPath 自定义配置文件路径和名称 2 FCKConfigFCKConfig EditorAreaCSS FCKConfig BasePath css fck editorar
  • MATLAB 图像平移操作(转)

    function outImage immove inImage Tx Ty m n size inImage Tx fix Tx Ty fix Ty move xif Tx lt 0 inImage imcrop inImage abs
  • Android 下拉选择框自定义view

    首先来看一下实现的效果 基本思路 继承PopupWindow的自定义View 说明 下图这部分自己布局 本文中主要说明的是点击某个分类显示的下拉实现 第一步 自定义 SpinnerPopuwindow继承PopupWindow Create
  • Markdown编写公式

    文章目录 Markdown编写公式 一 修改设置 二 希腊字母 三 一些数据结构 四 定界符 五 可变大小的符号 六 函数名称 七 二进制运算符和关系运算符 八 箭头符号 九 其他特殊符号 十 上下标 十一 矩阵 十二 分段函数 1 分段函
  • 集群篇-k8s介绍

    TOC 集群篇 k8s介绍 一 集群业务介绍 集群篇 服务器的搭建 集群的管理 运维 1 集群业务介绍 集群 k8s及自动化部署 服务器的预警监控功能 二 k8s 集群部署 K8S部署 DevOps 百度云地址 提取码 1111 1 k8s
  • 扫雷(C语言版)

    引言 扫雷游戏是一款经典的逻辑游戏 它不仅考验玩家的观察力和决策能力 还能带给玩家休闲娱乐的乐趣 本文将介绍一个简单的扫雷游戏的实现 帮助读者了解这款游戏的基本原理和代码实现 一 游戏规则简介 扫雷游戏的目标是找到所有没有地雷的方块 同时避
  • 服务器操作系统的实时性,对虚拟化操作系统进行实时性调度的解决方案介绍

    图3 中断实时响应分析 虚拟操作系统应用中常会有以下3类事件的实时响应需要考虑 0类事件 底层硬件中断需要得到上层某个Domain的快速响应处理 1类事件 Domain GuestOS 之间的通信事件需要被另一个Doamin快速处理 2 类
  • Portal_JS,用JS实现的Portlet效果

    有一年多没有关顾自己的博客了 然还有部分博友造访 令我万分感动 现在发布一下最近的一个组件 PortletWin package ElementUtils js author 熊水林 xionglb 163 com version 版权所有
  • Linux驱动-编译驱动模块的Makefile和脚本

    Makefile内容 ARCH arm CROSS COMPILE arm poky linux gnueabi 也可以同时编译多个模块 obj m export symbol o export symbol1 o export symbo
  • Shell函数的7种用法介绍

    1 在shell文件内部定义函数并引用 复制代码代码如下 shell function cat factorial sh bin bash function factorial factorial 1 for i 1 i lt 1 i do
  • 为什么每家公司都需要协作工具?

    前言 企业很多时候 和一个人是一样一样一样的 经营 也和一个人的成长是一样一样一样的 作为企业的管理者 如何健康存续的运营公司 是每个合格CEO不断成长路径上的必修课 就像 谈谈SaaS创业和企业服务的常识 中提到的企业服务常识 今天和大家
  • MySQL要不要容器化?能不能运行在Docker?

    文章目录 概述 数据安全问题 性能问题 状态问题 资源隔离方面 MySQL 其实也是容器化 概述 容器的定义 容器是为了解决 在切换运行环境时 如何保证软件能够正常运行 这一问题 目前 容器和 Docker 依旧是技术领域最热门的词语 无状
  • 嵌入式系统之KPN网络图

    specification model 推荐用于并行程序 进程通过无线规格的FIFO队列进行通信 读 具有破坏性和阻塞 一个进程停留在waiting队列直到它被另外一个进程的通道传输 写 非阻塞 一个进程不能阻止一个通道传输数据 KPN图像

随机推荐

  • MySQL数据库迁移详细步骤

    转载自 http sofar blog 51cto com 353572 1598364 一 背景简介 1 问题描述 由于机房搬迁 需要对后台DB服务器进行迁移 同时为了保证在数据迁移过程中 对线上业务不造成影响 并能够做到秒级切换 如果我
  • 腾讯云服务器部署使用教程_新手入门

    腾讯云服务器使用教程包括注册账号实名认证 选择云服务器CVM或轻量应用服务器CPU内存带宽和系统盘配置 安全设置和云服务器远程连接 安全组端口开通教程 云服务器环境部署以搭建网站为例手把手网站上线 云服务器文件传输和数据备份以及技术支持等详
  • 第1章 Python简介(1)

    第1章 Python简介 Python语言是一种面向对象的解释型高级编程语言 由Guido van Rossum于1989年底发明 第一个公开发行版发行于1991年 目前 Python语言有两个版本 Python 2 x和Python 3
  • stm32控制OLED显示实验(IIC、汉字显示)

    OLED c include stm32f10x h include OLED Font h 引脚配置 define OLED W SCL x GPIO WriteBit GPIOB GPIO Pin 10 BitAction x defi
  • 几种求最小公倍数的方法

    http blog csdn net iwm next article details 7450424 这是原链接 谢谢该博主的分享 写的很不错哦
  • cocoapods的安装与使用心得整理

    一 安装命令 sudo gem install cocoapods pod setup 这个时候需要耐心的等待哈 如果网络慢的话 需要等更久呢 每一行命令都会有回应的 如果遇到报错如下 Error fetching https rubyge
  • range 函数生成可迭代对象,for_in

    range 函数生成可迭代对象 for in range start stop step start 可选参数 默认为 0 表示序列起点 stop 必选参数 表示序列终点 不包括终点 step 可选参数 序列的步长 默认为 1 print
  • 软件自动化测试基本流程(附流程图)

    自动化测试与软件开发过程从本质上来讲是一样的 无非是利用自动化测试工具 相当于软件开发工具 经过对测试需求的分析 软件过程中的需求分析 设计出自动化测试用例 软件过程中的需求规格 从而搭建自动化测试的框架 软件过程中的概要设计 设计与编写自
  • ubuntu安装python3.6 software-properties-common

    gnupg 破坏 software properties common lt 0 96 24 3 but sudo apt install only upgrade gnupg
  • DKVMN学习

    文章目录 前言 Memory Augmented Neural Network MANN for Knowledge Tracing DKVMN模型 实验结果 DKVMN总结 DKVMN BORUTA模型 SKVMN模型 Deep IRT模
  • background-position设置百分比“失效了”!!

    1 background position设置百分比的计算原理 当指定百分比值的时候 实际上执行了以下的计算公式 该公式可以用数学方式定义图片和容器相对位置重合 这是当background size auto 时 百分比有效 contain
  • 组装一台1u服务器

    1 服务器的内存条都是带校验功能的 2 服务器cpu可以多个 一般电脑只有一个
  • NAS个人云存储服务器搭建

    NAS Network Attached Storage 网络附属存储 通过网络提供数据访问服务 可以理解为长时间连网的存储设备 其功能基本和市面上的各种云盘相似 它以数据为中心 将存储设备与服务器彻底分离 集中管理数据 从而释放带家 提高
  • layui 时间选择器laydate开始时间结束时间限制,及设置默认时分秒

    这个时间控件实现了 开始时间和结束时间都不得超过当前时间 结束时间大于开始时间并且小于当前时间 开始时间默认时分秒为00 00 00 结束时间默认时分秒为23 59 59 其他官方自带功能 项目中的需求是 结束时间要大于开始时间 包括时分秒
  • 全网页截图教程,如何截图截全屏

    系统自身的截屏快捷键 台式键盘的电脑 全屏 Ctrl Print Screen 当前窗口 Alt Print Screen 笔记本截图快捷键 FN Prt sc 浏览器自带的 非常好用 在浏览器打开要截取全网页为图片的那个网页 打开那个网页
  • Unity—常用API(续Time类)

    今天整理了Time类 一张很有意思的理解API的图 此图灵感来源于 如何理解API API 是如何工作的 仁杰兄的博客 CSDN博客 api 目录 Time 练习 使用Text制作倒计时预制体 在Update每帧执行的方法中 个别语句实现指
  • ubuntu学习(四)----文件写入操作编程

    1 write函数的详解 ssize t write int fd const void buf size t count 参数说明 fd 是文件描述符 write所对应的是写 即就是1 buf 通常是一个字符串 需要写入的字符串 coun
  • 浅析芝麻信用分征信体系

    在互联网大佬中 能将未雨绸缪之功力炼至极致的非马云莫属了 其所扔下的每一个棋子都会前思三招 后推九步 每一步商业布局都像是一枚运气极佳的的种子总能找到温润肥沃的土壤而后破土而发 十年遮风 百年纳凉 马老板曾苦心孤诣费尽心机地想把淘宝由一家广
  • 教你自己搭建一个ip池(绝对超好用!!!!)

    随着我们爬虫的速度越来越快 很多时候 有人发现 数据爬不了啦 打印出来一看 不返回数据 而且还甩一句话 是不是很熟悉啊 要想想看 人是怎么访问网站的 发请求 对 那么就会带有 request headers 那么当你疯狂请求别人的网站时候
  • .NET/C#下html转PDF,PDF加水印,PDF转图片

    一 添加OpenHtmlToPdf iTextSharp O2S Components PDFRender4NET引用 1 OpenHtmlToPdf 是一个 NET库 开源的 用于将HTML文档呈现为PDF格式 github地址 http