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中将每页要重复的部分画进去。)
bash 复制代码
PdfEventHandler handler = new PdfEventHandler(model, KT, ST, CN);//
  • pdf增加Event,将创建的类新增到pdf中:
bash 复制代码
pdf.AddEventHandler(PdfDocumentEvent.START_PAGE, handler);

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

bash 复制代码
 /// <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.4
     LowerMoney = 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、画双横线

csharp 复制代码
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、创作二维码

csharp 复制代码
//设置扫描二维码后显示的文字或内容
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;
}
相关推荐
friklogff1 小时前
【无标题】云端之C#:全面解析6种云服务提供商的SDK
开发语言·flask·c#
c#上位机2 小时前
C#事件的用法
java·javascript·c#
chnyi6_ya2 小时前
一些写leetcode的笔记
笔记·leetcode·c#
IT规划师3 小时前
C#|.net core 基础 - 扩展数组添加删除性能最好的方法
c#·.netcore·数组
时光追逐者3 小时前
分享6个.NET开源的AI和LLM相关项目框架
人工智能·microsoft·ai·c#·.net·.netcore
friklogff4 小时前
【C#生态园】提升C#开发效率:深入了解自然语言处理库与工具
开发语言·c#·区块链
__water12 小时前
『功能项目』回调函数处理死亡【54】
c#·回调函数·unity引擎
__water12 小时前
『功能项目』眩晕图标显示【52】
c#·unity引擎·动画事件
__water13 小时前
『功能项目』第二职业法师的平A【57】
c#·unity引擎·魔法球伤害传递
__water15 小时前
『功能项目』战士的伤害型技能【45】
c#·unity引擎·战士职业伤害型技能