C#使用iTextSharp添加PDF水印
作者:恝置 发布时间:2021-10-09 08:59:27
标签:C#,iTextSharp,水印
使用的是iTextSharp添加PDF水印,由于是接口动态生成PDF,所以采用的是全部是内存流的形式,而且水印是平铺是。iTextSharp版本是5.5。
/// <summary>
/// 添加倾斜水印
/// </summary>
/// <param name="pdfStream">pdf文件流</param>
/// <param name="waterMarkName">水印字符串</param>
/// <param name="width">页面宽度</param>
/// <param name="height">页面高度</param>
public MemoryStream SetWaterMark(MemoryStream pdfStream, string waterMarkName, float width, float height)
{
try
{
int fontSize = 50;//设置字体大小
int span = 40;//设置垂直位移
MemoryStream outStream = new MemoryStream();
PdfReader pdfReader = new PdfReader(pdfStream);
PdfStamper pdfStamper = new PdfStamper(pdfReader, outStream);
pdfStamper.Writer.CloseStream = false;
int total = pdfReader.NumberOfPages + 1;
PdfContentByte content;
BaseFont font = BaseFont.CreateFont(@"C:\WINDOWS\Fonts\STCAIYUN.TTF", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);//华文云彩字体
PdfGState gs = new PdfGState();
gs.FillOpacity = 0.15f;//透明度
int waterMarkNameLenth = waterMarkName.Length;
char c;
int rise = 0;
string spanString = " ";//水平位移
for (int i = 1; i < total; i++)
{
rise = waterMarkNameLenth * span;
content = pdfStamper.GetOverContent(i);//在内容上方加水印
//content = pdfStamper.GetUnderContent(i);//在内容下方加水印
content.SetGState(gs);
content.BeginText();
content.SetColorFill(BaseColor.GREEN);
content.SetFontAndSize(font, fontSize);
int heightNumbert = (int)Math.Ceiling((decimal)height / (decimal)rise);//垂直重复的次数,进一发
int panleWith = (fontSize + span) * waterMarkNameLenth;
int widthNumber = (int)Math.Ceiling((decimal)width / (decimal)panleWith);//水平重复次数
// 设置水印文字字体倾斜 开始
for (int w = 0; w < widthNumber; w++)
{
for (int h = 1; h <= heightNumbert; h++)
{
int yleng = rise * h;
content.SetTextMatrix(w * panleWith, yleng);//x,y设置水印开始的绝对左边,以左下角为x,y轴的起点
for (int k = 0; k < waterMarkNameLenth; k++)
{
content.SetTextRise(yleng);//指定的y轴值处添加
c = waterMarkName[k];
content.ShowText(c + spanString);
yleng -= span;
}
}
}
content.EndText();
}
if (pdfStamper != null)
pdfStamper.Close();
if (pdfReader != null)
pdfReader.Close();
return outStream;
}
catch (Exception ex)
{
throw ex;
}
}


猜你喜欢
- 题目要求思路一:模拟迭代依次判断每个节点是否合法:左子树判断是否>low,合法就向左下走,不合法往右下;右子树判断是否<high
- 注:完整项目下载在处理了核心任务之后,我们会发现有些请求并不是都是静态的,那么我们就需要进行实现处理动态请求的要求,如下面代码是我们请求的解
- 在Android开发中,我们经常遇到Android读取图片大小超过屏幕显示的图(一般只要显示一定规格的预览图即可),在图片特别多或者图片显示
- 前言 * 体系是Struts2框架的重要组成部分,不夸张的说,没有 * 体系,也就没有这么好用的Struts2框架了。在Struts2框架中
- 我们在上网的过程中经常看到各种图片,那你知道它是如何实现的吗?接下来就让我们一块探讨一下。 网络图片的浏览可以分为俩部分,基本的页面布局与界
- Android 自动获取验证码的两种方式分别是BroadcastReceiver及ContentObserver,两种方式都需要进行注册、取
- 方法一:using System;using System.Collections.Generic;using System.Compon
- 原理很简单,利用Path画一个图,然后用动画进行播放,播放时间由依赖属性输入赋值与控件内部维护的一个计时器进行控制。控件基本是玩具,无法作为
- 函数名称 说明ActiveKeyboardLayout 激活一个不同的键盘布局,该布局必须先由 LoadKeyBoardLayout函数装载
- 开发中经常需要将某个文件向另一个应用程序传递,如图片上传到另一个应用程序、文件在不同存储路径之间的复制粘贴等都需要共享文件,可以这样理解接收
- C# 复制与删除文件的实现方法1、首先是复制文件首先打开我们的对话框获得文件路径,当然也可以直接编写路径private void BtnAd
- 一、简介SpringBoot 最强大的功能就是把我们常用的场景抽取成了一个个starter(场景启动器),我们通过引入SpringBoot
- 一、是什么当下很多公司都采取前后端分离的开发模式,前端和后端的工作由不同的工程师完成。在这种开发模式下,维持一份及时更新且完整的 Rest
- 树的结构说得差不多了,现在我们来说说一种数据结构叫做哈希表(hash table),哈希表有是干什么用的呢?我们知道树的操作的时间复杂度通常
- SpringMVC的几个模型对象模型对象的作用主要是保存数据,可以借助它们将数据带到前端。常用的模型对象有以下几个:1.ModelAndVi
- static 表示静态,它可以修饰属性,方法和代码块。1.static修饰属性(类变量),那么这个属性就可以用类名.属性名来访问,也就是使这
- 本文实例讲述了Android实现在一个activity中添加多个listview的方法。分享给大家供大家参考,具体如下:listview的i
- 一 模式介绍重试模式,是应用在异常处理中,发生异常的时候,能够对业务程序进行重新调用,在实际中,可以使用Polly提供稳定,简单的用法,自己
- 前言:因为项目中显示图片是用Picasso,设置placeholder和error图片的时候发现,本地图片的大小无法满足我的需求,需要先对图
- C#接口的学习,在编程中,我们经常会用到接口,那什么是接口呢?接口描述的是可属于任何类或结构的一组相关功能,所以实现接口的类或结构必须实现接