当前位置: 首页 > news >正文

iText7画发票PDF——小tips

itext7教程:

1、https://blog.csdn.net/allway2/article/details/124295097
2、https://max.book118.com/html/2017/0720/123235195.shtm
3、https://www.cnblogs.com/fonks/p/15090635.html
4、https://www.cnblogs.com/sky-chen/p/13026203.html
5、官方:https://api.itextpdf.com/iText/dotnet/8.0.2/classi_text_1_1_layout_1_1_splitting_1_1_keep_all_split_characters.html
6、git:https://github.com/itext/itext7-dotnet

1.毫米转换磅
itext中是用磅值作为像素位置点的。为方便画PDF,则需要把常规毫米转换成磅值;
转换规则:毫米/10/2.54f*72

2.添加每页的固定表头
(给pdf添加AddEventHandler)

  • 创建类PdfEventHandler
    (在PdfEventHandler中将每页要重复的部分画进去。)
PdfEventHandler handler = new PdfEventHandler(model, KT, ST, CN);//
  • pdf增加Event,将创建的类新增到pdf中:
pdf.AddEventHandler(PdfDocumentEvent.START_PAGE, handler);

3.金额转换成中文大写金额

 /// <summary>/// 金额转换成中文大写金额/// </summary>/// <param name="LowerMoney">传入的数字金额,eg:10.74</param>/// <returns></returns>private static string MoneyToUpper(string LowerMoney){string functionReturnValue = null;bool IsNegative = false; // 是否是负数if (LowerMoney.Trim().Substring(0, 1) == "-"){// 是负数则先转为正数LowerMoney = LowerMoney.Trim().Remove(0, 1);IsNegative = true;}string strLower = null;string strUpart = null;string strUpper = null;int iTemp = 0;// 保留两位小数 123.489→123.49  123.4→123.4LowerMoney = Math.Round(double.Parse(LowerMoney), 2).ToString();if (LowerMoney.IndexOf(".") > 0){if (LowerMoney.IndexOf(".") == LowerMoney.Length - 2){LowerMoney = LowerMoney + "0";}}else{LowerMoney = LowerMoney + ".00";}strLower = LowerMoney;iTemp = 1;strUpper = "";while (iTemp <= strLower.Length){switch (strLower.Substring(strLower.Length - iTemp, 1)){case ".":strUpart = "圆";break;case "0":strUpart = "零";break;case "1":strUpart = "壹";break;case "2":strUpart = "贰";break;case "3":strUpart = "叁";break;case "4":strUpart = "肆";break;case "5":strUpart = "伍";break;case "6":strUpart = "陆";break;case "7":strUpart = "柒";break;case "8":strUpart = "捌";break;case "9":strUpart = "玖";break;}switch (iTemp){case 1:strUpart = strUpart + "分";break;case 2:strUpart = strUpart + "角";break;case 3:strUpart = strUpart + "";break;case 4:strUpart = strUpart + "";break;case 5:strUpart = strUpart + "拾";break;case 6:strUpart = strUpart + "佰";break;case 7:strUpart = strUpart + "仟";break;case 8:strUpart = strUpart + "万";break;case 9:strUpart = strUpart + "拾";break;case 10:strUpart = strUpart + "佰";break;case 11:strUpart = strUpart + "仟";break;case 12:strUpart = strUpart + "亿";break;case 13:strUpart = strUpart + "拾";break;case 14:strUpart = strUpart + "佰";break;case 15:strUpart = strUpart + "仟";break;case 16:strUpart = strUpart + "万";break;default:strUpart = strUpart + "";break;}strUpper = strUpart + strUpper;iTemp = iTemp + 1;}strUpper = strUpper.Replace("零拾", "零");strUpper = strUpper.Replace("零佰", "零");strUpper = strUpper.Replace("零仟", "零");strUpper = strUpper.Replace("零零零", "零");strUpper = strUpper.Replace("零零", "零");strUpper = strUpper.Replace("零角零分", "整");strUpper = strUpper.Replace("零分", "整");strUpper = strUpper.Replace("零角", "零");strUpper = strUpper.Replace("零亿零万零圆", "亿圆");strUpper = strUpper.Replace("亿零万零圆", "亿圆");strUpper = strUpper.Replace("零亿零万", "亿");strUpper = strUpper.Replace("零万零圆", "万圆");strUpper = strUpper.Replace("零亿", "亿");strUpper = strUpper.Replace("零万", "万");strUpper = strUpper.Replace("零圆", "圆");strUpper = strUpper.Replace("零零", "零");Console.WriteLine("零角零分");// 对壹圆以下的金额的处理if (strUpper.Substring(0, 1) == "圆"){strUpper = strUpper.Substring(1, strUpper.Length - 1);}if (strUpper.Substring(0, 1) == "零"){strUpper = strUpper.Substring(1, strUpper.Length - 1);}if (strUpper.Substring(0, 1) == "角"){strUpper = strUpper.Substring(1, strUpper.Length - 1);}if (strUpper.Substring(0, 1) == "分"){strUpper = strUpper.Substring(1, strUpper.Length - 1);}if (strUpper.Substring(0, 1) == "整"){strUpper = "零圆整";}functionReturnValue = strUpper;if (IsNegative == true){return "负" + functionReturnValue;}else{return string.Format(functionReturnValue, Encoding.GetEncoding("GB2312"));}}

4、画双横线
在这里插入图片描述

pdfCanvas.MoveTo(computeValue.computeUnit(141), computeValue.computeUnit(278.5f));
pdfCanvas.LineTo(computeValue.computeUnit(69), computeValue.computeUnit(278.5f));
pdfCanvas.SetStrokeColor(new DeviceRgb(128, 0, 0));
pdfCanvas.MoveTo(computeValue.computeUnit(141), computeValue.computeUnit(277.5f));
pdfCanvas.LineTo(computeValue.computeUnit(69), computeValue.computeUnit(277.5f));
pdfCanvas.SetStrokeColor(new DeviceRgb(128, 0, 0));
pdfCanvas.ClosePathStroke();

5、创作二维码

//设置扫描二维码后显示的文字或内容
string code = $"01,{发票票种model},," + 发票号码model + "," + 价税合计model + "," + DateTime.Parse(开票日期model).ToString("yyyyMMdd") + ",,";
//将code与转换为CRC16编码后的字节链接
code = code + CRC16(System.Text.Encoding.UTF8.GetBytes(code));
//将链接好的字符串转换为二维码字节
model.qrCode = GetQrCode(code);//model.qrCode为byte[]类型
//在Canvas中添加动态二维码(具体实现可参考下一篇笔记(iText7——画发票PDF(完整)))Image EWM = new Image(ImageDataFactory.Create(_model.qrCode)).SetWidth(computeValue.computeUnit(20)).SetHeight(computeValue.computeUnit(20));canvas.Add(EWM.SetFixedPosition(1, computeValue.computeUnit(7), computeValue.computeUnit(271)));
//若要在二维码中间放图片,则加上图片:
Image S = new Image(ImageDataFactory.Create("E://图片//发票图片//Shui.png")).SetWidth(computeValue.computeUnit(4)).SetHeight(computeValue.computeUnit(4));
canvas.Add(S.SetFixedPosition(1, computeValue.computeUnit(15), computeValue.computeUnit((float)279)));/// <summary>
/// CRC16编码
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
private static string CRC16(byte[] data)
{ushort crc = 0xFFFF;int len = data.Length;for (int i = 0; i < len; i++){crc = (ushort)((crc >> 8) ^ data[i]);for (int j = 0; j < 8; j++)crc = (crc & 1) == 1 ? (ushort)((crc >> 1) ^ 0xA001) : (ushort)(crc >> 1);}return string.Format("{0:X}", crc).PadLeft(4, '0');
}/// <summary>
/// 生成发票二维码
/// </summary>
/// <returns></returns>
private static byte[] GetQrCode(string codeValue)
{// 设定二维码大小QrCodeEncodingOptions qrCode = new QrCodeEncodingOptions();qrCode.ErrorCorrection = ErrorCorrectionLevel.M;qrCode.CharacterSet = "UTF-8";qrCode.Height = 180;qrCode.Width = 180;qrCode.Margin = 1;// 生成二维码BarcodeWriter writer = new BarcodeWriter();writer.Format = BarcodeFormat.QR_CODE;writer.Options = qrCode;writer.Options.PureBarcode = true; // 不显示条码下面的数据Bitmap bitmap = writer.Write(codeValue);MemoryStream ms = new MemoryStream();bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);byte[] arr = new byte[ms.Length];ms.Position = 0;ms.Read(arr, 0, (int)ms.Length);ms.Close();return arr;
}

相关文章:

iText7画发票PDF——小tips

itext7教程&#xff1a; 1、https://blog.csdn.net/allway2/article/details/124295097 2、https://max.book118.com/html/2017/0720/123235195.shtm 3、https://www.cnblogs.com/fonks/p/15090635.html 4、https://www.cnblogs.com/sky-chen/p/13026203.html 5、官方&#xff…...

跟着刘二大人学pytorch(第---10---节课之卷积神经网络)

文章目录 0 前言0.1 课程链接&#xff1a;0.2 课件下载地址&#xff1a; 回忆卷积卷积过程&#xff08;以输入为单通道、1个卷积核为例&#xff09;卷积过程&#xff08;以输入为3通道、1个卷积核为例&#xff09;卷积过程&#xff08;以输入为N通道、1个卷积核为例&#xff09…...

transformer实战

1.pipeline() 首先下载transformer&#xff0c;之后 from transformers import pipeline# 加载一个用于文本分类的pipeline # Use a pipeline as a high-level helperpipe pipeline("zero-shot-classification", model"https://hf-mirror.com/morit/chinese_…...

【Starrocks docker-compose部署】

一、docker-compose部署starrocks 官方的docker-compose地址:docker-compose地址 version: "3.9" services:starrocks-fe-0:image: starrocks/fe-ubuntu:latesthostname: starrocks-fe-0container_name: starrocks-fe-0command:- /bin/bash- -c- |/opt/starrocks/f…...

Nginx 精解:正则表达式、location 匹配与 rewrite 重写

一、常见的 Nginx 正则表达式 在 Nginx 配置中&#xff0c;正则表达式用于匹配和重写 URL 请求。以下是一些常见的 Nginx 正则表达式示例&#xff1a; 当涉及正则表达式时&#xff0c;理解各个特殊字符的含义是非常重要的。以下是每个特殊字符的例子&#xff1a; ^&#xff1…...

代码随想录算法训练营Day37|56.合并区间、738.单调递增的数字、968.监控二叉树

合并区间 56. 合并区间 - 力扣&#xff08;LeetCode&#xff09; 和之前的思路类似&#xff0c;先创建一个ans二维数组&#xff0c;创建start和end来指明添加进入ans数组的区间下标&#xff0c;先对数组按照首元素排序从小到大排序后&#xff0c;根据当前元素是否小于下一个元…...

Web前端开发12章:深入探索与实战解析

Web前端开发12章&#xff1a;深入探索与实战解析 在数字化浪潮的推动下&#xff0c;Web前端开发技术日新月异&#xff0c;成为了构建互联网应用的重要基石。本文将以12章的篇幅&#xff0c;从四个方面、五个方面、六个方面和七个方面&#xff0c;深入探索Web前端开发的精髓&am…...

八股操作系统和计算机网络

5.线程间的同步的方式有哪些&#xff1f; 6.PCB(不熟悉) 进程状态 什么是僵尸进程和孤儿进程&#xff1f; 进程调度算法 死锁的理解 举个发生死锁的例子 解决死锁的方式 内存管理做了哪些事情 什么是内存碎片 常见的内存管理 段表通过什么数据结构实现地址映射 分段机制为什么会…...

正能量情感语录热门素材文案去哪里找?文案素材网站分享

正能量情感语录热门素材文案去哪里找&#xff1f;文案素材网站分享 想为你的作品注入正能量和情感温度&#xff1f;不知如何获取热门情感语录素材&#xff1f;别担心&#xff0c;今天我将为大家推荐一些海外知名的素材网站&#xff0c;让你轻松找到受欢迎的文案素材&#xff…...

bean实例化

黑马程序员SSM 文章目录 一、bean是如何创建的二、实例化bean的三种方式3.1 构造方法&#xff08;常用&#xff09;3.2 静态工厂3.3 实例化工厂&#xff08;了解&#xff09;3.4 FactoryBean 一、bean是如何创建的 Spring 创建bean的时候使用的是无参构造 二、实例化bean的三…...

Django中间件探索:揭秘中间件在Web应用中的守护角色与实战应用

系列文章目录 Django入门全攻略&#xff1a;从零搭建你的第一个Web项目Django ORM入门指南&#xff1a;从概念到实践&#xff0c;掌握模型创建、迁移与视图操作Django ORM实战&#xff1a;模型字段与元选项配置&#xff0c;以及链式过滤与QF查询详解Django ORM深度游&#xff…...

【PL理论】(24) C- 语言:有块的作用域 | 更新的语法 | 新的语义域 | 环境 vs. 内存

&#x1f4ad; 写在前面&#xff1a;我们将再次扩展之前的C语言&#xff0c;让我们向这种语言引入“作用域”的概念。 目录 0x00 C- 语言&#xff1a;有块的作用域 0x01 C- 语言&#xff1a;更新的语法 0x02 新的语义域 0x03 环境 vs. 内存 0x00 C- 语言&#xff1a;有块的…...

React native 使用Animated 优化连续setState 性能问题

再部分场景下我们需要连续更新state刷新页面。一般情况刷新使用setstate没有问题&#xff0c;当需要连续刷新的情况会有明显的性能问题。 场景&#xff1a;自定义可拖动抽屉组件 新增需求在抽屉活动是更新主页面组件样式&#xff0c;此时需要动态传递抽屉高度修改主页组件属性…...

Qt中的事件循环

Gui框架一般都是基于事件驱动的&#xff0c;Qt也不例外&#xff0c;在 Qt 框架中&#xff0c;事件循环&#xff08;Event Loop&#xff09;是一个核心机制&#xff0c;负责管理和分发应用程序中的所有事件和消息。它确保了应用程序能够响应用户输入、定时器事件、窗口系统事件等…...

JVM常用概念之线程本地分配缓冲区(ThreadLocal Allocation Buffer,TLAB)

当实例化一个Java类时&#xff0c;运行时环境必须为相关实例分配存储空间&#xff0c;在JRE中此存储空间分配操作是由内存管理器实现的&#xff08;其实是JVM的垃圾回收器&#xff09;&#xff0c;由于内存管理器通常使用与运行时目标语言不同的语言编写&#xff08;例如&#…...

大模型生成的常见Top-k、Top-p、Temperature参数

参考&#xff1a; https://zhuanlan.zhihu.com/p/669661536 topK&#xff0c;topP https://www.douyin.com/video/7380126984573127945 主要是softmax产生的词表每个词的概率分布后&#xff0c; topK&#xff0c;比如K3&#xff0c;表示采样概率最大的前3个&#xff0c;其他全…...

ppt添加圆角矩形,并调整圆角弧度方法

一、背景 我们看的论文&#xff0c;许多好看的图都是用PPT做的&#xff0c;下面介绍用ppt添加圆角矩形&#xff0c;并调整圆角弧度方法。 二、ppt添加圆角矩形&#xff0c;并调整圆角弧度 添加矩形&#xff1a; 在顶部工具栏中&#xff0c;点击“插入”选项卡。 在“插图”…...

测评要求+基本措施+对应产品

基本要求项测评项基本措施对应产品 网络架构 网络架构 网络架构应保证网络各个部分的带宽满足业务高峰期需要&#xff1b;带宽管理流量控制系统 网络架构 网络架构 网络架构应避免将重要网络区域部署在边界处&#xff0c;重要网络区域与其他网络区域之间应采取可靠的技术隔离手…...

什么是git?

前言 Git 是一款免费、开源的分布式版本控制系统&#xff0c;用于敏捷高效地处理任何或小或大的项目。是的&#xff0c;我对git的介绍就一条&#xff0c;想看简介的可以去百度一下&#x1f618;&#x1f618;&#x1f618; 为什么要用git&#xff1f; OK&#xff0c;想象一下…...

C/C++中内存开辟与柔性数组

C/C中内存的开辟 在C中&#xff0c;我们都知道有三个区&#xff1a; 1. 栈区&#xff08;stack&#xff09;&#xff1a;在执行函数时&#xff0c;函数内局部变量的存储单元都可以在栈上创建&#xff0c;函数执行结 束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指…...

模型参数、模型存储精度、参数与显存

模型参数量衡量单位 M&#xff1a;百万&#xff08;Million&#xff09; B&#xff1a;十亿&#xff08;Billion&#xff09; 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的&#xff0c;但是一个参数所表示多少字节不一定&#xff0c;需要看这个参数以什么…...

Java 8 Stream API 入门到实践详解

一、告别 for 循环&#xff01; 传统痛点&#xff1a; Java 8 之前&#xff0c;集合操作离不开冗长的 for 循环和匿名类。例如&#xff0c;过滤列表中的偶数&#xff1a; List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

C++使用 new 来创建动态数组

问题&#xff1a; 不能使用变量定义数组大小 原因&#xff1a; 这是因为数组在内存中是连续存储的&#xff0c;编译器需要在编译阶段就确定数组的大小&#xff0c;以便正确地分配内存空间。如果允许使用变量来定义数组的大小&#xff0c;那么编译器就无法在编译时确定数组的大…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用

文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么&#xff1f;1.1.2 感知机的工作原理 1.2 感知机的简单应用&#xff1a;基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...

Python竞赛环境搭建全攻略

Python环境搭建竞赛技术文章大纲 竞赛背景与意义 竞赛的目的与价值Python在竞赛中的应用场景环境搭建对竞赛效率的影响 竞赛环境需求分析 常见竞赛类型&#xff08;算法、数据分析、机器学习等&#xff09;不同竞赛对Python版本及库的要求硬件与操作系统的兼容性问题 Pyth…...

热门Chrome扩展程序存在明文传输风险,用户隐私安全受威胁

赛门铁克威胁猎手团队最新报告披露&#xff0c;数款拥有数百万活跃用户的Chrome扩展程序正在通过未加密的HTTP连接静默泄露用户敏感数据&#xff0c;严重威胁用户隐私安全。 知名扩展程序存在明文传输风险 尽管宣称提供安全浏览、数据分析或便捷界面等功能&#xff0c;但SEMR…...

Canal环境搭建并实现和ES数据同步

作者&#xff1a;田超凡 日期&#xff1a;2025年6月7日 Canal安装&#xff0c;启动端口11111、8082&#xff1a; 安装canal-deployer服务端&#xff1a; https://github.com/alibaba/canal/releases/1.1.7/canal.deployer-1.1.7.tar.gz cd /opt/homebrew/etc mkdir canal…...

【笔记】AI Agent 项目 SUNA 部署 之 Docker 构建记录

#工作记录 构建过程记录 Microsoft Windows [Version 10.0.27871.1000] (c) Microsoft Corporation. All rights reserved.(suna-py3.12) F:\PythonProjects\suna>python setup.py --admin███████╗██╗ ██╗███╗ ██╗ █████╗ ██╔════╝…...

C++11 constexpr和字面类型:从入门到精通

文章目录 引言一、constexpr的基本概念与使用1.1 constexpr的定义与作用1.2 constexpr变量1.3 constexpr函数1.4 constexpr在类构造函数中的应用1.5 constexpr的优势 二、字面类型的基本概念与使用2.1 字面类型的定义与作用2.2 字面类型的应用场景2.2.1 常量定义2.2.2 模板参数…...

__VUE_PROD_HYDRATION_MISMATCH_DETAILS__ is not explicitly defined.

这个警告表明您在使用Vue的esm-bundler构建版本时&#xff0c;未明确定义编译时特性标志。以下是详细解释和解决方案&#xff1a; ‌问题原因‌&#xff1a; 该标志是Vue 3.4引入的编译时特性标志&#xff0c;用于控制生产环境下SSR水合不匹配错误的详细报告1使用esm-bundler…...