import 'dart:async'; import 'dart:typed_data'; import 'package:flyinsonolite/consultation/reports/reporttemplate/borders.dart'; import 'package:flyinsonolite/consultation/reports/reporttemplate/interfaces/position_layout.dart'; import 'package:flyinsonolite/consultation/reports/reporttemplate/rt_Cell.dart'; import 'package:flyinsonolite/consultation/reports/reporttemplate/rt_border.dart'; import 'package:flyinsonolite/consultation/reports/reporttemplate/rt_color.dart'; import 'package:flyinsonolite/consultation/reports/reporttemplate/rt_thickness.dart'; import 'package:pdf/pdf.dart'; import 'package:pdf/widgets.dart' as pw; import 'package:dio/dio.dart' as dio; /// 当前类根据报告模板样式生成对应的pdf3.8.1的样式 class ReportStyleHelper { ///根据RTThickness生成Pdf的EdgeInsets static pw.EdgeInsets convertRTMargin(RTThickness? margin) { if (margin != null) { var leftReal = margin.left!; var topReal = margin.top!; var rightReal = margin.right!; var bottomReal = margin.bottom!; var pwMargin = pw.EdgeInsets.only( left: leftReal * PdfPageFormat.point, top: topReal * PdfPageFormat.point, right: rightReal * PdfPageFormat.point, bottom: bottomReal * PdfPageFormat.point, ); return pwMargin; } return const pw.EdgeInsets.only(); } ///根据RTColor生成PdfColor ///PdfColors输入参数要求是RGBA各个值占据一个字符大小空间的百分比 ///因此需要double的保留精度的除法运算 static PdfColor getPDFColorFromRTColor(RTColor rtcolor) { return PdfColor(rtcolor.r! / 255.0, rtcolor.g! / 255.0, rtcolor.b! / 255.0, rtcolor.a! / 255.0); } /// 根据RTBorderStyle生成PDF的border style /// 其中Dashdot、dashdotdot 是根据pdf element的border绘制机制做的转换。 static pw.BorderStyle getPDFBorderStyle(RTBorderStyle rtBorderStyle) { if (rtBorderStyle == RTBorderStyle.None) { return pw.BorderStyle.none; } if (rtBorderStyle == RTBorderStyle.Dash) { return pw.BorderStyle.dashed; } if (rtBorderStyle == RTBorderStyle.Dot) { return pw.BorderStyle.dotted; } if (rtBorderStyle == RTBorderStyle.Solid) { return pw.BorderStyle.solid; } if (rtBorderStyle == RTBorderStyle.DashDot) { return const pw.BorderStyle(pattern: [2, 2]); } if (rtBorderStyle == RTBorderStyle.DashDotDot) { return const pw.BorderStyle(pattern: [2, 1]); } return const pw.BorderStyle(); } ///根据RTCell 获得PDF对应的BoxDecoration static pw.BoxDecoration getPDFCellBorderBox(RTCell rtCell) { var cellColor = getPDFColorFromRTColor(rtCell.background!); var cellBorder = getPDFBorder(rtCell.borders!); var cellDecoration = pw.BoxDecoration(border: cellBorder, color: cellColor); return cellDecoration; } static pw.BoxDecoration getAllBlackBorderDecoration(RTCell rtCell) { var cellColor = getPDFColorFromRTColor(rtCell.background!); var cellDecoration = pw.BoxDecoration( border: pw.Border.all(color: PdfColors.black), color: cellColor); return cellDecoration; } ///根据Borders 获得PDF对应的Border static pw.Border getPDFBorder(Borders borders) { var left = getPDFBorderSide(borders.left); var top = getPDFBorderSide(borders.top); var right = getPDFBorderSide(borders.right); var bottom = getPDFBorderSide(borders.bottom); var border = pw.Border(left: left, top: top, right: right, bottom: bottom); return border; } ///根据RTBorder 获得PDF对应的BorderSide static pw.BorderSide getPDFBorderSide(RTBorder border) { var borderStyle = getPDFBorderStyle(border.borderStyle); var color = getPDFColorFromRTColor(border.color); var borderSide = pw.BorderSide( width: border.thickness, style: borderStyle, color: color); return borderSide; } ///根据HorizontalLayout 获得PDF对应的行MainAxisAlignment static pw.MainAxisAlignment getRowMainAisAlign(HorizontalLayout hor) { if (hor == HorizontalLayout.Center) { return pw.MainAxisAlignment.center; } if (hor == HorizontalLayout.Right) { return pw.MainAxisAlignment.end; } return pw.MainAxisAlignment.start; } ///根据HorizontalLayout 获得PDF对应的行Aling static pw.Alignment? getRowMainAlign(HorizontalLayout hor, {bool hasLeft = false}) { if (hor == HorizontalLayout.Center) { return pw.Alignment.centerLeft; } if (hor == HorizontalLayout.Right) { return pw.Alignment.centerRight; } if (hasLeft) { if (hor == HorizontalLayout.Left) { return pw.Alignment.centerLeft; } } return null; } ///根据HorizontalLayout 获得PDF对应的行CrossAxisAlignment static pw.CrossAxisAlignment getColumnCrossAisAlign(HorizontalLayout hor) { if (hor == HorizontalLayout.Center) { return pw.CrossAxisAlignment.center; } if (hor == HorizontalLayout.Right) { return pw.CrossAxisAlignment.end; } if (hor == HorizontalLayout.Stretch) { return pw.CrossAxisAlignment.start; } return pw.CrossAxisAlignment.start; } ///根据Vertical 获得PDF对应的列MainAxisAlignment static pw.MainAxisAlignment getColumnMainAisAlign(VerticalLayout ver) { if (ver == VerticalLayout.Center) { return pw.MainAxisAlignment.center; } if (ver == VerticalLayout.Top) { return pw.MainAxisAlignment.start; } if (ver == VerticalLayout.Bottom) { return pw.MainAxisAlignment.end; } if (ver == VerticalLayout.Stretch) { return pw.MainAxisAlignment.start; } return pw.MainAxisAlignment.start; } ///根据Hor 获得PDF对应的Wrap的Alignment static pw.WrapAlignment getWrapAlignment(HorizontalLayout ver) { if (ver == HorizontalLayout.Center) { return pw.WrapAlignment.center; } if (ver == HorizontalLayout.Left) { return pw.WrapAlignment.start; } if (ver == HorizontalLayout.Right) { return pw.WrapAlignment.end; } return pw.WrapAlignment.start; } ///根据Ver 获得PDF对应的Wrap的CrossAlign static pw.WrapCrossAlignment getWrapCrossAlignment(VerticalLayout ver) { if (ver == VerticalLayout.Center) { return pw.WrapCrossAlignment.center; } if (ver == VerticalLayout.Bottom) { return pw.WrapCrossAlignment.end; } return pw.WrapCrossAlignment.center; } ///根据verticalLayout 获得PDF对应的行纵轴布局方式 static pw.CrossAxisAlignment getCrossAsiAlign(VerticalLayout verticalLayout) { if (verticalLayout == VerticalLayout.Bottom) { return pw.CrossAxisAlignment.end; } if (verticalLayout == VerticalLayout.Center) { return pw.CrossAxisAlignment.center; } if (verticalLayout == VerticalLayout.Stretch) { return pw.CrossAxisAlignment.stretch; } if (verticalLayout == VerticalLayout.Top) { return pw.CrossAxisAlignment.start; } return pw.CrossAxisAlignment.start; } /// 根据 verticalLayout 和 horizontalLayout 获取首个子元素对齐方式 static pw.Alignment getChildAlignment(RTCell cellElement) { if (cellElement.blocks == null || cellElement.blocks!.isEmpty) { return pw.Alignment.center; } VerticalLayout verticalLayout = cellElement.blocks![0].verticalAlignment!; HorizontalLayout horizontalLayout = cellElement.blocks![0].horizontalAlignment!; pw.Alignment alignment = _getAlignmentByLayout(verticalLayout, horizontalLayout); return alignment; } static pw.Alignment _getAlignmentByLayout( VerticalLayout verticalLayout, HorizontalLayout horizontalLayout) { pw.Alignment alignment = pw.Alignment.center; switch (verticalLayout) { case VerticalLayout.Top: switch (horizontalLayout) { case HorizontalLayout.Left: alignment = pw.Alignment.topLeft; break; case HorizontalLayout.Center: alignment = pw.Alignment.topCenter; break; case HorizontalLayout.Right: alignment = pw.Alignment.topRight; break; case HorizontalLayout.Stretch: alignment = pw.Alignment.topLeft; break; } break; case VerticalLayout.Center: switch (horizontalLayout) { case HorizontalLayout.Left: alignment = pw.Alignment.centerLeft; break; case HorizontalLayout.Center: alignment = pw.Alignment.center; break; case HorizontalLayout.Right: alignment = pw.Alignment.centerRight; break; case HorizontalLayout.Stretch: alignment = pw.Alignment.centerLeft; break; } break; case VerticalLayout.Bottom: switch (horizontalLayout) { case HorizontalLayout.Left: alignment = pw.Alignment.bottomLeft; break; case HorizontalLayout.Center: alignment = pw.Alignment.bottomCenter; break; case HorizontalLayout.Right: alignment = pw.Alignment.bottomRight; break; case HorizontalLayout.Stretch: alignment = pw.Alignment.bottomLeft; break; } break; case VerticalLayout.Stretch: switch (horizontalLayout) { case HorizontalLayout.Left: alignment = pw.Alignment.centerLeft; break; case HorizontalLayout.Center: alignment = pw.Alignment.center; break; case HorizontalLayout.Right: alignment = pw.Alignment.centerRight; break; case HorizontalLayout.Stretch: alignment = pw.Alignment.centerLeft; break; } break; } return alignment; } ///根据图片地址获取MemoryImage static Future getMemoryImage(String imageUrl) async { var value = await getDataFromNetwork(imageUrl); return value!; } /// 从链接获取Vid信息 /// /// [url] vid文件链接 static Future getDataFromNetwork(String url) async { try { final httpClient = dio.Dio(dio.BaseOptions( responseType: dio.ResponseType.bytes, sendTimeout: 10 * 1000, )); final response = await httpClient.get(url); httpClient.close(); final bytes = response.data as Uint8List; return bytes; } catch (e) { // logger return null; } } }