• 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.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、画双横线
    在这里插入图片描述

    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)));
    
    
    /// 
    /// CRC16编码
    /// 
    /// 
    /// 
    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');
    }
    
    /// 
    /// 生成发票二维码
    /// 
    /// 
    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;
    }
    
  • 相关阅读:
    【HTML专栏2】VSCode的使用(新建HTML文件)
    mysql bin_log日志恢复数据
    iTOP-RK3568开发板内核模块实验-设置交叉编译器
    Java面试题-Java核心基础-第七天(String)
    Rustdesk安装教程
    TCP粘包问题解决方案
    mybatisplus逻辑删除
    Mybatis按年月日时分秒查询,MySQL年月日时分秒查询
    Vert.x学习笔记-什么是Verticle
    我和谷歌共成长-资深安卓开发的转型之路
  • 原文地址:https://blog.csdn.net/qq_51462774/article/details/139657533