Files
workavia-mail-front/core/lib/utils/print_utils.dart
T
2024-03-08 13:40:12 +07:00

400 lines
11 KiB
Dart

import 'dart:async';
import 'package:core/data/model/print_attachment.dart';
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/utils/app_logger.dart';
import 'package:flutter/services.dart';
import 'package:htmltopdfwidgets/htmltopdfwidgets.dart' as pw;
import 'package:intl/intl.dart';
import 'package:printing/printing.dart';
class PrintUtils {
final pw.HTMLToPdf _htmlToPdf;
final ImagePaths _imagePaths;
PrintUtils(this._htmlToPdf, this._imagePaths);
Future<pw.Widget> _createEmailContentWidget(String htmlDocument) async {
try {
final List<pw.Widget> bodyWidgets = await _htmlToPdf.convert(htmlDocument);
return pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
...bodyWidgets
]
);
} catch (e) {
logError('PrintUtils::_createEmailContentWidget: Exception: $e');
return pw.Text(htmlDocument);
}
}
List<pw.Widget> _createBodyWidgets({
required pw.Context context,
required String logoAppSvg,
required String appName,
required String userName,
required String title,
required String htmlDocument,
required String senderName,
required String senderEmailAddress,
required String dateTime,
required String toPrefix,
required String ccPrefix,
required String bccPrefix,
required String replyToPrefix,
required String titleAttachment,
required pw.Widget contentWidget,
String? toAddress,
String? ccAddress,
String? bccAddress,
String? replyToAddress,
List<PrintAttachment>? listAttachment,
}) {
return [
pw.Container(
padding: const pw.EdgeInsets.symmetric(horizontal: 32),
child: pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
_createUserInformationRow(
context: context,
logoAppSvg: logoAppSvg,
appName: appName,
userName: userName
),
_createPageDivider(),
if (title.isNotEmpty)
...[
_createTitleRow(
context: context,
title: title
),
_createPageDivider(),
],
pw.SizedBox(height: 12),
pw.Row(
children: [
pw.Expanded(
child: _createSenderWidget(
context: context,
name: senderName,
emailAddress: senderEmailAddress
)
),
_createDateTimeWidget(
context: context,
dateTime: dateTime
)
]
),
if (replyToAddress?.isNotEmpty == true)
_createRecipientRow(
prefix: replyToPrefix,
emailAddress: replyToAddress!
),
if (toAddress?.isNotEmpty == true)
_createRecipientRow(
prefix: toPrefix,
emailAddress: toAddress!
),
if (ccAddress?.isNotEmpty == true)
_createRecipientRow(
prefix: ccPrefix,
emailAddress: ccAddress!
),
if (bccAddress?.isNotEmpty == true)
_createRecipientRow(
prefix: bccPrefix,
emailAddress: bccAddress!
),
pw.Padding(
padding: const pw.EdgeInsets.symmetric(
horizontal: 12,
vertical: 24),
child: contentWidget
),
if (listAttachment?.isNotEmpty == true)
...[
_createPageDivider(),
pw.SizedBox(height: 12),
_createAttachmentTitle(
context: context,
title: titleAttachment,
totalAttachments: listAttachment!.length
),
pw.SizedBox(height: 4),
...listAttachment.map((attachment) => _createAttachmentRow(
context: context,
attachment: attachment
))
]
]
)
)
];
}
pw.Widget _createPageDivider() {
return pw.Padding(
padding: const pw.EdgeInsets.only(top: 12),
child: pw.Divider()
);
}
pw.Widget _createPageHeader({
required pw.Context context,
required String appName,
required String title,
required String locale,
}) {
final currentTime = DateFormat('MM/dd/yyyy, h:mm a', locale).format(DateTime.now());
return pw.Padding(
padding: const pw.EdgeInsets.all(20),
child: pw.Row(
children: [
pw.Text(
currentTime,
style: pw.Theme.of(context).defaultTextStyle.copyWith(
fontSize: 8,
color: pw.PdfColor.fromInt(AppColor.colorTextBody.value)
)
),
pw.SizedBox(width: 16),
pw.Expanded(
child: pw.Text(
'$appName - $title',
textAlign: pw.TextAlign.center,
maxLines: 1,
style: pw.Theme.of(context).defaultTextStyle.copyWith(
fontSize: 8,
color: pw.PdfColor.fromInt(AppColor.colorTextBody.value)
)
)
),
]
)
);
}
pw.Widget _createUserInformationRow({
required pw.Context context,
required String logoAppSvg,
required String appName,
required String userName,
}) {
return pw.Row(
children: [
pw.SvgImage(
svg: logoAppSvg,
width: 32,
height: 32
),
pw.SizedBox(width: 12),
pw.Text(
appName,
style: pw.Theme.of(context).header0
),
pw.Spacer(),
pw.SizedBox(width: 12),
pw.Text(
userName,
style: pw.Theme.of(context).header4
)
]
);
}
pw.Widget _createTitleRow({
required pw.Context context,
required String title,
}) {
return pw.Padding(
padding: const pw.EdgeInsets.only(top: 12),
child: pw.Text(
title,
style: pw.Theme.of(context).header3
)
);
}
pw.Widget _createSenderWidget({
required pw.Context context,
required String name,
required String emailAddress,
}) {
return pw.Row(
children: [
if (name.isNotEmpty)
pw.Padding(
padding: const pw.EdgeInsetsDirectional.only(end: 4),
child: pw.Text(
name,
style: pw.Theme.of(context).header4
)
),
pw.Text('<$emailAddress>')
]
);
}
pw.Widget _createDateTimeWidget({
required pw.Context context,
required String dateTime,
}) {
return pw.Text(
dateTime,
style: pw.Theme.of(context).defaultTextStyle.copyWith(
fontSize: 10,
color: pw.PdfColor.fromInt(AppColor.colorTextBody.value)
)
);
}
pw.Widget _createRecipientRow({
required String prefix,
required String emailAddress,
}) {
return pw.Row(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
pw.Text('$prefix:'),
pw.SizedBox(width: 4),
pw.Expanded(child: pw.Text(emailAddress))
]
);
}
pw.Widget _createAttachmentTitle({
required pw.Context context,
required String title,
required int totalAttachments,
}) {
return pw.Text(
'$totalAttachments $title',
style: pw.Theme.of(context).header4
);
}
pw.Widget _createAttachmentRow({
required pw.Context context,
required PrintAttachment attachment,
}) {
return pw.Padding(
padding: const pw.EdgeInsets.only(top: 8),
child: pw.Row(
children: [
pw.SvgImage(
svg: attachment.iconSvg,
width: 24,
height: 24
),
pw.SizedBox(width: 8),
pw.Expanded(
child: pw.Column(
mainAxisSize: pw.MainAxisSize.min,
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
pw.Text(
attachment.name,
style: pw.Theme.of(context).header4
),
pw.Text(attachment.size)
]
)
),
]
)
);
}
Future<bool> printEmailToPDF({
required String appName,
required String userName,
required String title,
required String emailContent,
required String senderName,
required String senderEmailAddress,
required String locale,
required String dateTime,
required String toPrefix,
required String ccPrefix,
required String bccPrefix,
required String replyToPrefix,
required String titleAttachment,
String? toAddress,
String? ccAddress,
String? bccAddress,
String? replyToAddress,
List<PrintAttachment>? listAttachment,
}) async {
return await Printing.layoutPdf(onLayout: (pw.PdfPageFormat format) async {
final googleInterRegularFont = await PdfGoogleFonts.interRegular();
final googleInterBoldFont = await PdfGoogleFonts.interBold();
final logoAppSvg = await rootBundle.loadString(_imagePaths.icTMailLogo);
final contentWidget = await _createEmailContentWidget(emailContent);
final pdfDocument = pw.Document();
pdfDocument.addPage(
pw.MultiPage(
pageFormat: pw.PdfPageFormat.standard,
orientation: pw.PageOrientation.portrait,
theme: pw.ThemeData(
defaultTextStyle: pw.TextStyle(
font: googleInterRegularFont,
fontSize: 12,
color: pw.PdfColors.black
),
header3: pw.TextStyle(
font: googleInterBoldFont,
fontSize: 14,
fontWeight: pw.FontWeight.bold,
color: pw.PdfColors.black
),
header4: pw.TextStyle(
font: googleInterBoldFont,
fontSize: 12,
fontWeight: pw.FontWeight.bold,
color: pw.PdfColors.black
),
),
margin: pw.EdgeInsets.zero,
build: (context) => _createBodyWidgets(
context: context,
contentWidget: contentWidget,
logoAppSvg: logoAppSvg,
appName: appName,
userName: userName,
title: title,
htmlDocument: emailContent,
senderName: senderName,
senderEmailAddress: senderEmailAddress,
dateTime: dateTime,
toPrefix: toPrefix,
ccPrefix: ccPrefix,
bccPrefix: toPrefix,
replyToPrefix: replyToPrefix,
toAddress: toAddress,
ccAddress: ccAddress,
bccAddress: bccAddress,
replyToAddress: replyToAddress,
titleAttachment: titleAttachment,
listAttachment: listAttachment
),
header: (context) => _createPageHeader(
context: context,
appName: appName,
title: title,
locale: locale,
),
)
);
return await pdfDocument.save();
});
}
}