143 lines
4.5 KiB
Dart
143 lines
4.5 KiB
Dart
import 'dart:io';
|
|
import 'package:pdf/widgets.dart' as pw;
|
|
import 'package:pdf/pdf.dart';
|
|
import 'package:intl/intl.dart';
|
|
import 'package:path_provider/path_provider.dart';
|
|
|
|
class PdfExporter {
|
|
/// 🔹 Ekspor satu data pelanggan ke file PDF
|
|
static Future<String> exportSingleItemToPdf(
|
|
Map<String, dynamic> item, {
|
|
String format = 'A6', // 🔹 default A6
|
|
}) async {
|
|
final pdf = pw.Document();
|
|
final dateFormat = DateFormat('dd MMM yyyy, HH:mm', 'id_ID');
|
|
final createdAt = item['created_at'] != null
|
|
? dateFormat.format(item['created_at'])
|
|
: '-';
|
|
|
|
// Tentukan ukuran halaman berdasarkan format
|
|
final pageFormat = switch (format.toUpperCase()) {
|
|
'A4' => PdfPageFormat.a4,
|
|
'A5' => PdfPageFormat.a5,
|
|
_ => PdfPageFormat.a6, // default A6
|
|
};
|
|
|
|
// Pastikan total nominal berupa angka
|
|
final totalNominal = num.tryParse(item['total']?.toString() ?? '0') ?? 0;
|
|
|
|
// Ambil data toko (jika ada)
|
|
final store = item['store'] ?? {};
|
|
final namaToko = store['namaToko'] ?? '-';
|
|
final alamatToko = store['alamat'] ?? '-';
|
|
final noHpToko = store['noHp'] ?? '-';
|
|
final noRegistrasi = store['noRegistrasi'] ?? '-';
|
|
final keteranganToko = store['keterangan'] ?? '-';
|
|
|
|
pdf.addPage(
|
|
pw.Page(
|
|
pageFormat: pageFormat, // 🔹 gunakan ukuran halaman sesuai format
|
|
margin: const pw.EdgeInsets.all(12),
|
|
build: (pw.Context context) {
|
|
return pw.Column(
|
|
crossAxisAlignment: pw.CrossAxisAlignment.start,
|
|
children: [
|
|
pw.Center(
|
|
child: pw.Text(
|
|
'DATA PENGIRIMAN',
|
|
style: pw.TextStyle(
|
|
fontSize: 14,
|
|
fontWeight: pw.FontWeight.bold,
|
|
),
|
|
),
|
|
),
|
|
pw.SizedBox(height: 6),
|
|
_buildRow('Nama Penerima', item['penerima']),
|
|
_buildRow('No. WA', item['no_wa']),
|
|
_buildRow('Alamat', item['alamat']),
|
|
_buildRow('Kota', item['kota']),
|
|
_buildRow('Provinsi', item['provinsi']),
|
|
_buildRow('Barang', item['barang']),
|
|
_buildRow(
|
|
'Total Nominal',
|
|
'Rp ${NumberFormat('#,##0', 'id_ID').format(totalNominal)}',
|
|
),
|
|
_buildRow('Pembayaran', item['pembayaran']),
|
|
_buildRow('Tanggal Dibuat', createdAt),
|
|
pw.SizedBox(height: 6),
|
|
pw.Divider(thickness: 0.8),
|
|
|
|
pw.SizedBox(height: 4),
|
|
pw.Text(
|
|
'DATA TOKO PENGIRIM',
|
|
style: pw.TextStyle(
|
|
fontSize: 12,
|
|
fontWeight: pw.FontWeight.bold,
|
|
),
|
|
),
|
|
pw.SizedBox(height: 4),
|
|
_buildRow('Nama Toko', namaToko),
|
|
_buildRow('Alamat Toko', alamatToko),
|
|
_buildRow('No. HP Toko', noHpToko),
|
|
_buildRow('No. Registrasi', noRegistrasi),
|
|
_buildRow('Keterangan', keteranganToko),
|
|
|
|
pw.Spacer(),
|
|
pw.Center(
|
|
child: pw.Text(
|
|
'Dicetak otomatis oleh sistem Praresi',
|
|
style: const pw.TextStyle(fontSize: 8),
|
|
),
|
|
),
|
|
],
|
|
);
|
|
},
|
|
),
|
|
);
|
|
|
|
// 🔹 Simpan ke folder Download (Android)
|
|
Directory? downloadDir;
|
|
if (Platform.isAndroid) {
|
|
downloadDir = Directory('/storage/emulated/0/Download');
|
|
} else {
|
|
downloadDir = await getApplicationDocumentsDirectory();
|
|
}
|
|
|
|
final filePath =
|
|
'${downloadDir.path}/Data_Pengiriman_${DateFormat('yyyyMMdd_HHmmss').format(DateTime.now())}_$format.pdf';
|
|
|
|
final file = File(filePath);
|
|
await file.writeAsBytes(await pdf.save());
|
|
|
|
return filePath;
|
|
}
|
|
|
|
/// 🔹 Komponen baris label dan isi
|
|
static pw.Widget _buildRow(String label, dynamic value) {
|
|
return pw.Padding(
|
|
padding: const pw.EdgeInsets.symmetric(vertical: 1.5),
|
|
child: pw.Row(
|
|
crossAxisAlignment: pw.CrossAxisAlignment.start,
|
|
children: [
|
|
pw.Container(
|
|
width: 90,
|
|
child: pw.Text(
|
|
label,
|
|
style: pw.TextStyle(
|
|
fontWeight: pw.FontWeight.bold,
|
|
fontSize: 9.5,
|
|
),
|
|
),
|
|
),
|
|
pw.Expanded(
|
|
child: pw.Text(
|
|
value?.toString() ?? '-',
|
|
style: const pw.TextStyle(fontSize: 9.5),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|