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;
}
相关推荐
fkdw1 小时前
C# Newtonsoft.Json 反序列化派生类数据丢失问题
c#·json
浅尝辄止;4 小时前
C# 异步编程
c#
ou.cs7 小时前
c# 实现一个简单的异常日志记录(异常迭代+分片+定时清理)+AOP Rougamo全局注入
c#
一只小小汤圆9 小时前
编译笔记:vs 中 正在从以下位置***加载符号 C# 中捕获C/C++抛出的异常
c++·c#
码农君莫笑9 小时前
Blazor项目中使用EF读写 SQLite 数据库
linux·数据库·sqlite·c#·.netcore·人机交互·visual studio
呆呆小雅10 小时前
C#关键字volatile
java·redis·c#
boligongzhu10 小时前
DALSA工业相机SDK二次开发(图像采集及保存)C#版
开发语言·c#·dalsa
web1478621072310 小时前
C# .Net Web 路由相关配置
前端·c#·.net
Jasmine_llq11 小时前
《 火星人 》
算法·青少年编程·c#