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教程: 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、官方ÿ…...
跟着刘二大人学pytorch(第---10---节课之卷积神经网络)
文章目录 0 前言0.1 课程链接:0.2 课件下载地址: 回忆卷积卷积过程(以输入为单通道、1个卷积核为例)卷积过程(以输入为3通道、1个卷积核为例)卷积过程(以输入为N通道、1个卷积核为例)…...
transformer实战
1.pipeline() 首先下载transformer,之后 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 配置中,正则表达式用于匹配和重写 URL 请求。以下是一些常见的 Nginx 正则表达式示例: 当涉及正则表达式时,理解各个特殊字符的含义是非常重要的。以下是每个特殊字符的例子: ^࿱…...
代码随想录算法训练营Day37|56.合并区间、738.单调递增的数字、968.监控二叉树
合并区间 56. 合并区间 - 力扣(LeetCode) 和之前的思路类似,先创建一个ans二维数组,创建start和end来指明添加进入ans数组的区间下标,先对数组按照首元素排序从小到大排序后,根据当前元素是否小于下一个元…...
Web前端开发12章:深入探索与实战解析
Web前端开发12章:深入探索与实战解析 在数字化浪潮的推动下,Web前端开发技术日新月异,成为了构建互联网应用的重要基石。本文将以12章的篇幅,从四个方面、五个方面、六个方面和七个方面,深入探索Web前端开发的精髓&am…...
八股操作系统和计算机网络
5.线程间的同步的方式有哪些? 6.PCB(不熟悉) 进程状态 什么是僵尸进程和孤儿进程? 进程调度算法 死锁的理解 举个发生死锁的例子 解决死锁的方式 内存管理做了哪些事情 什么是内存碎片 常见的内存管理 段表通过什么数据结构实现地址映射 分段机制为什么会…...
正能量情感语录热门素材文案去哪里找?文案素材网站分享
正能量情感语录热门素材文案去哪里找?文案素材网站分享 想为你的作品注入正能量和情感温度?不知如何获取热门情感语录素材?别担心,今天我将为大家推荐一些海外知名的素材网站,让你轻松找到受欢迎的文案素材ÿ…...
bean实例化
黑马程序员SSM 文章目录 一、bean是如何创建的二、实例化bean的三种方式3.1 构造方法(常用)3.2 静态工厂3.3 实例化工厂(了解)3.4 FactoryBean 一、bean是如何创建的 Spring 创建bean的时候使用的是无参构造 二、实例化bean的三…...
Django中间件探索:揭秘中间件在Web应用中的守护角色与实战应用
系列文章目录 Django入门全攻略:从零搭建你的第一个Web项目Django ORM入门指南:从概念到实践,掌握模型创建、迁移与视图操作Django ORM实战:模型字段与元选项配置,以及链式过滤与QF查询详解Django ORM深度游ÿ…...
【PL理论】(24) C- 语言:有块的作用域 | 更新的语法 | 新的语义域 | 环境 vs. 内存
💭 写在前面:我们将再次扩展之前的C语言,让我们向这种语言引入“作用域”的概念。 目录 0x00 C- 语言:有块的作用域 0x01 C- 语言:更新的语法 0x02 新的语义域 0x03 环境 vs. 内存 0x00 C- 语言:有块的…...
React native 使用Animated 优化连续setState 性能问题
再部分场景下我们需要连续更新state刷新页面。一般情况刷新使用setstate没有问题,当需要连续刷新的情况会有明显的性能问题。 场景:自定义可拖动抽屉组件 新增需求在抽屉活动是更新主页面组件样式,此时需要动态传递抽屉高度修改主页组件属性…...
Qt中的事件循环
Gui框架一般都是基于事件驱动的,Qt也不例外,在 Qt 框架中,事件循环(Event Loop)是一个核心机制,负责管理和分发应用程序中的所有事件和消息。它确保了应用程序能够响应用户输入、定时器事件、窗口系统事件等…...
JVM常用概念之线程本地分配缓冲区(ThreadLocal Allocation Buffer,TLAB)
当实例化一个Java类时,运行时环境必须为相关实例分配存储空间,在JRE中此存储空间分配操作是由内存管理器实现的(其实是JVM的垃圾回收器),由于内存管理器通常使用与运行时目标语言不同的语言编写(例如&#…...
大模型生成的常见Top-k、Top-p、Temperature参数
参考: https://zhuanlan.zhihu.com/p/669661536 topK,topP https://www.douyin.com/video/7380126984573127945 主要是softmax产生的词表每个词的概率分布后, topK,比如K3,表示采样概率最大的前3个,其他全…...
ppt添加圆角矩形,并调整圆角弧度方法
一、背景 我们看的论文,许多好看的图都是用PPT做的,下面介绍用ppt添加圆角矩形,并调整圆角弧度方法。 二、ppt添加圆角矩形,并调整圆角弧度 添加矩形: 在顶部工具栏中,点击“插入”选项卡。 在“插图”…...
测评要求+基本措施+对应产品
基本要求项测评项基本措施对应产品 网络架构 网络架构 网络架构应保证网络各个部分的带宽满足业务高峰期需要;带宽管理流量控制系统 网络架构 网络架构 网络架构应避免将重要网络区域部署在边界处,重要网络区域与其他网络区域之间应采取可靠的技术隔离手…...
什么是git?
前言 Git 是一款免费、开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。是的,我对git的介绍就一条,想看简介的可以去百度一下😘😘😘 为什么要用git? OK,想象一下…...
C/C++中内存开辟与柔性数组
C/C中内存的开辟 在C中,我们都知道有三个区: 1. 栈区(stack):在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结 束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
云计算——弹性云计算器(ECS)
弹性云服务器:ECS 概述 云计算重构了ICT系统,云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台,包含如下主要概念。 ECS(Elastic Cloud Server):即弹性云服务器,是云计算…...
椭圆曲线密码学(ECC)
一、ECC算法概述 椭圆曲线密码学(Elliptic Curve Cryptography)是基于椭圆曲线数学理论的公钥密码系统,由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA,ECC在相同安全强度下密钥更短(256位ECC ≈ 3072位RSA…...
Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...
多场景 OkHttpClient 管理器 - Android 网络通信解决方案
下面是一个完整的 Android 实现,展示如何创建和管理多个 OkHttpClient 实例,分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
04-初识css
一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...
智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...
全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...
