reportstylehelper.dart 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. import 'dart:async';
  2. import 'dart:typed_data';
  3. import 'package:flyinsonolite/consultation/reports/reporttemplate/borders.dart';
  4. import 'package:flyinsonolite/consultation/reports/reporttemplate/interfaces/position_layout.dart';
  5. import 'package:flyinsonolite/consultation/reports/reporttemplate/rt_Cell.dart';
  6. import 'package:flyinsonolite/consultation/reports/reporttemplate/rt_border.dart';
  7. import 'package:flyinsonolite/consultation/reports/reporttemplate/rt_color.dart';
  8. import 'package:flyinsonolite/consultation/reports/reporttemplate/rt_thickness.dart';
  9. import 'package:pdf/pdf.dart';
  10. import 'package:pdf/widgets.dart' as pw;
  11. import 'package:dio/dio.dart' as dio;
  12. /// 当前类根据报告模板样式生成对应的pdf3.8.1的样式
  13. class ReportStyleHelper {
  14. ///根据RTThickness生成Pdf的EdgeInsets
  15. static pw.EdgeInsets convertRTMargin(RTThickness? margin) {
  16. if (margin != null) {
  17. var leftReal = margin.left!;
  18. var topReal = margin.top!;
  19. var rightReal = margin.right!;
  20. var bottomReal = margin.bottom!;
  21. var pwMargin = pw.EdgeInsets.only(
  22. left: leftReal * PdfPageFormat.point,
  23. top: topReal * PdfPageFormat.point,
  24. right: rightReal * PdfPageFormat.point,
  25. bottom: bottomReal * PdfPageFormat.point,
  26. );
  27. return pwMargin;
  28. }
  29. return const pw.EdgeInsets.only();
  30. }
  31. ///根据RTColor生成PdfColor
  32. ///PdfColors输入参数要求是RGBA各个值占据一个字符大小空间的百分比
  33. ///因此需要double的保留精度的除法运算
  34. static PdfColor getPDFColorFromRTColor(RTColor rtcolor) {
  35. return PdfColor(rtcolor.r! / 255.0, rtcolor.g! / 255.0, rtcolor.b! / 255.0,
  36. rtcolor.a! / 255.0);
  37. }
  38. /// 根据RTBorderStyle生成PDF的border style
  39. /// 其中Dashdot、dashdotdot 是根据pdf element的border绘制机制做的转换。
  40. static pw.BorderStyle getPDFBorderStyle(RTBorderStyle rtBorderStyle) {
  41. if (rtBorderStyle == RTBorderStyle.None) {
  42. return pw.BorderStyle.none;
  43. }
  44. if (rtBorderStyle == RTBorderStyle.Dash) {
  45. return pw.BorderStyle.dashed;
  46. }
  47. if (rtBorderStyle == RTBorderStyle.Dot) {
  48. return pw.BorderStyle.dotted;
  49. }
  50. if (rtBorderStyle == RTBorderStyle.Solid) {
  51. return pw.BorderStyle.solid;
  52. }
  53. if (rtBorderStyle == RTBorderStyle.DashDot) {
  54. return const pw.BorderStyle(pattern: <int>[2, 2]);
  55. }
  56. if (rtBorderStyle == RTBorderStyle.DashDotDot) {
  57. return const pw.BorderStyle(pattern: <int>[2, 1]);
  58. }
  59. return const pw.BorderStyle();
  60. }
  61. ///根据RTCell 获得PDF对应的BoxDecoration
  62. static pw.BoxDecoration getPDFCellBorderBox(RTCell rtCell) {
  63. var cellColor = getPDFColorFromRTColor(rtCell.background!);
  64. var cellBorder = getPDFBorder(rtCell.borders!);
  65. var cellDecoration = pw.BoxDecoration(border: cellBorder, color: cellColor);
  66. return cellDecoration;
  67. }
  68. static pw.BoxDecoration getAllBlackBorderDecoration(RTCell rtCell) {
  69. var cellColor = getPDFColorFromRTColor(rtCell.background!);
  70. var cellDecoration = pw.BoxDecoration(
  71. border: pw.Border.all(color: PdfColors.black), color: cellColor);
  72. return cellDecoration;
  73. }
  74. ///根据Borders 获得PDF对应的Border
  75. static pw.Border getPDFBorder(Borders borders) {
  76. var left = getPDFBorderSide(borders.left);
  77. var top = getPDFBorderSide(borders.top);
  78. var right = getPDFBorderSide(borders.right);
  79. var bottom = getPDFBorderSide(borders.bottom);
  80. var border = pw.Border(left: left, top: top, right: right, bottom: bottom);
  81. return border;
  82. }
  83. ///根据RTBorder 获得PDF对应的BorderSide
  84. static pw.BorderSide getPDFBorderSide(RTBorder border) {
  85. var borderStyle = getPDFBorderStyle(border.borderStyle);
  86. var color = getPDFColorFromRTColor(border.color);
  87. var borderSide = pw.BorderSide(
  88. width: border.thickness, style: borderStyle, color: color);
  89. return borderSide;
  90. }
  91. ///根据HorizontalLayout 获得PDF对应的行MainAxisAlignment
  92. static pw.MainAxisAlignment getRowMainAisAlign(HorizontalLayout hor) {
  93. if (hor == HorizontalLayout.Center) {
  94. return pw.MainAxisAlignment.center;
  95. }
  96. if (hor == HorizontalLayout.Right) {
  97. return pw.MainAxisAlignment.end;
  98. }
  99. return pw.MainAxisAlignment.start;
  100. }
  101. ///根据HorizontalLayout 获得PDF对应的行Aling
  102. static pw.Alignment? getRowMainAlign(HorizontalLayout hor,
  103. {bool hasLeft = false}) {
  104. if (hor == HorizontalLayout.Center) {
  105. return pw.Alignment.centerLeft;
  106. }
  107. if (hor == HorizontalLayout.Right) {
  108. return pw.Alignment.centerRight;
  109. }
  110. if (hasLeft) {
  111. if (hor == HorizontalLayout.Left) {
  112. return pw.Alignment.centerLeft;
  113. }
  114. }
  115. return null;
  116. }
  117. ///根据HorizontalLayout 获得PDF对应的行CrossAxisAlignment
  118. static pw.CrossAxisAlignment getColumnCrossAisAlign(HorizontalLayout hor) {
  119. if (hor == HorizontalLayout.Center) {
  120. return pw.CrossAxisAlignment.center;
  121. }
  122. if (hor == HorizontalLayout.Right) {
  123. return pw.CrossAxisAlignment.end;
  124. }
  125. if (hor == HorizontalLayout.Stretch) {
  126. return pw.CrossAxisAlignment.start;
  127. }
  128. return pw.CrossAxisAlignment.start;
  129. }
  130. ///根据Vertical 获得PDF对应的列MainAxisAlignment
  131. static pw.MainAxisAlignment getColumnMainAisAlign(VerticalLayout ver) {
  132. if (ver == VerticalLayout.Center) {
  133. return pw.MainAxisAlignment.center;
  134. }
  135. if (ver == VerticalLayout.Top) {
  136. return pw.MainAxisAlignment.start;
  137. }
  138. if (ver == VerticalLayout.Bottom) {
  139. return pw.MainAxisAlignment.end;
  140. }
  141. if (ver == VerticalLayout.Stretch) {
  142. return pw.MainAxisAlignment.start;
  143. }
  144. return pw.MainAxisAlignment.start;
  145. }
  146. ///根据Hor 获得PDF对应的Wrap的Alignment
  147. static pw.WrapAlignment getWrapAlignment(HorizontalLayout ver) {
  148. if (ver == HorizontalLayout.Center) {
  149. return pw.WrapAlignment.center;
  150. }
  151. if (ver == HorizontalLayout.Left) {
  152. return pw.WrapAlignment.start;
  153. }
  154. if (ver == HorizontalLayout.Right) {
  155. return pw.WrapAlignment.end;
  156. }
  157. return pw.WrapAlignment.start;
  158. }
  159. ///根据Ver 获得PDF对应的Wrap的CrossAlign
  160. static pw.WrapCrossAlignment getWrapCrossAlignment(VerticalLayout ver) {
  161. if (ver == VerticalLayout.Center) {
  162. return pw.WrapCrossAlignment.center;
  163. }
  164. if (ver == VerticalLayout.Bottom) {
  165. return pw.WrapCrossAlignment.end;
  166. }
  167. return pw.WrapCrossAlignment.center;
  168. }
  169. ///根据verticalLayout 获得PDF对应的行纵轴布局方式
  170. static pw.CrossAxisAlignment getCrossAsiAlign(VerticalLayout verticalLayout) {
  171. if (verticalLayout == VerticalLayout.Bottom) {
  172. return pw.CrossAxisAlignment.end;
  173. }
  174. if (verticalLayout == VerticalLayout.Center) {
  175. return pw.CrossAxisAlignment.center;
  176. }
  177. if (verticalLayout == VerticalLayout.Stretch) {
  178. return pw.CrossAxisAlignment.stretch;
  179. }
  180. if (verticalLayout == VerticalLayout.Top) {
  181. return pw.CrossAxisAlignment.start;
  182. }
  183. return pw.CrossAxisAlignment.start;
  184. }
  185. /// 根据 verticalLayout 和 horizontalLayout 获取首个子元素对齐方式
  186. static pw.Alignment getChildAlignment(RTCell cellElement) {
  187. if (cellElement.blocks == null || cellElement.blocks!.isEmpty) {
  188. return pw.Alignment.center;
  189. }
  190. VerticalLayout verticalLayout = cellElement.blocks![0].verticalAlignment!;
  191. HorizontalLayout horizontalLayout =
  192. cellElement.blocks![0].horizontalAlignment!;
  193. pw.Alignment alignment =
  194. _getAlignmentByLayout(verticalLayout, horizontalLayout);
  195. return alignment;
  196. }
  197. static pw.Alignment _getAlignmentByLayout(
  198. VerticalLayout verticalLayout, HorizontalLayout horizontalLayout) {
  199. pw.Alignment alignment = pw.Alignment.center;
  200. switch (verticalLayout) {
  201. case VerticalLayout.Top:
  202. switch (horizontalLayout) {
  203. case HorizontalLayout.Left:
  204. alignment = pw.Alignment.topLeft;
  205. break;
  206. case HorizontalLayout.Center:
  207. alignment = pw.Alignment.topCenter;
  208. break;
  209. case HorizontalLayout.Right:
  210. alignment = pw.Alignment.topRight;
  211. break;
  212. case HorizontalLayout.Stretch:
  213. alignment = pw.Alignment.topLeft;
  214. break;
  215. }
  216. break;
  217. case VerticalLayout.Center:
  218. switch (horizontalLayout) {
  219. case HorizontalLayout.Left:
  220. alignment = pw.Alignment.centerLeft;
  221. break;
  222. case HorizontalLayout.Center:
  223. alignment = pw.Alignment.center;
  224. break;
  225. case HorizontalLayout.Right:
  226. alignment = pw.Alignment.centerRight;
  227. break;
  228. case HorizontalLayout.Stretch:
  229. alignment = pw.Alignment.centerLeft;
  230. break;
  231. }
  232. break;
  233. case VerticalLayout.Bottom:
  234. switch (horizontalLayout) {
  235. case HorizontalLayout.Left:
  236. alignment = pw.Alignment.bottomLeft;
  237. break;
  238. case HorizontalLayout.Center:
  239. alignment = pw.Alignment.bottomCenter;
  240. break;
  241. case HorizontalLayout.Right:
  242. alignment = pw.Alignment.bottomRight;
  243. break;
  244. case HorizontalLayout.Stretch:
  245. alignment = pw.Alignment.bottomLeft;
  246. break;
  247. }
  248. break;
  249. case VerticalLayout.Stretch:
  250. switch (horizontalLayout) {
  251. case HorizontalLayout.Left:
  252. alignment = pw.Alignment.centerLeft;
  253. break;
  254. case HorizontalLayout.Center:
  255. alignment = pw.Alignment.center;
  256. break;
  257. case HorizontalLayout.Right:
  258. alignment = pw.Alignment.centerRight;
  259. break;
  260. case HorizontalLayout.Stretch:
  261. alignment = pw.Alignment.centerLeft;
  262. break;
  263. }
  264. break;
  265. }
  266. return alignment;
  267. }
  268. ///根据图片地址获取MemoryImage
  269. static Future<Uint8List> getMemoryImage(String imageUrl) async {
  270. var value = await getDataFromNetwork(imageUrl);
  271. return value!;
  272. }
  273. /// 从链接获取Vid信息
  274. ///
  275. /// [url] vid文件链接
  276. static Future<Uint8List?> getDataFromNetwork(String url) async {
  277. try {
  278. final httpClient = dio.Dio(dio.BaseOptions(
  279. responseType: dio.ResponseType.bytes,
  280. sendTimeout: 10 * 1000,
  281. ));
  282. final response = await httpClient.get(url);
  283. httpClient.close();
  284. final bytes = response.data as Uint8List;
  285. return bytes;
  286. } catch (e) {
  287. // logger
  288. return null;
  289. }
  290. }
  291. }