syncfusion / flutter-widgets

Syncfusion Flutter widgets libraries include high quality UI widgets and file-format packages to help you create rich, high-quality applications for iOS, Android, and web from a single code base.
1.56k stars 759 forks source link

PDF Bottom Issue #1410

Closed Yuvabanna closed 6 months ago

Yuvabanna commented 1 year ago

This issue is coming in this that product ad is visible till the end of the page. I need bottom space, with the help of which I can add footer at the bottom and my footer does not overflow.

import 'dart:io';

import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:intl/intl.dart'; import 'package:open_filex/open_filex.dart'; import 'package:path_provider/path_provider.dart'; import 'package:share_plus/share_plus.dart'; import 'package:spl_invoice_creator/api/api_method.dart'; import 'package:spl_invoice_creator/utility/changable_value.dart'; import 'package:spl_invoice_creator/utility/image_manager.dart'; import 'package:syncfusion_flutter_pdf/pdf.dart';

class PDFGenerate { Future _readImageData() async { Alignment.center; final data = await rootBundle.load(ImageAsset.logo); return data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes); }

Future createPDF( customerName, address, city, country, postalCode, invoiceNo, reference, invoiceDate, invoiceDueDate, item, notes, amount, isOpen, isUpdate) async { DateTime year = DateTime.now();

final PdfDocument document = PdfDocument();

final page = document.pages.add();

PdfStandardFont pdfStandardFont() =>
    PdfStandardFont(PdfFontFamily.helvetica, 12,
        style: PdfFontStyle.regular);

final PdfGrid grid = getGrid(item);

page.graphics.drawImage(
  PdfBitmap(await _readImageData()),
  Rect.fromCenter(center: Offset.zero, height: 0, width: 0),
);

final Size pageSize = page.getClientSize();

page.graphics.drawString(
    'Invoice', PdfStandardFont(PdfFontFamily.helvetica, 35),
    bounds: const Rect.fromLTWH(0, 70, 0, 0));

page.graphics.drawString('Company Number : ${ChangeValue.companyNumber}',
    PdfStandardFont(PdfFontFamily.helvetica, 12),
    format: PdfStringFormat(alignment: PdfTextAlignment.left),
    bounds: const Rect.fromLTWH(0, 120, 0, 0));

page.graphics.drawString(ChangeValue.companyFullName,
    PdfStandardFont(PdfFontFamily.helvetica, 15),
    bounds: const Rect.fromLTWH(385, 0, 0, 50));

page.graphics.drawString(ChangeValue.companyAddress1Line,
    PdfStandardFont(PdfFontFamily.helvetica, 12),
    bounds: const Rect.fromLTWH(415, 20, 0, 0));

page.graphics.drawString(ChangeValue.companyAddress2Line,
    PdfStandardFont(PdfFontFamily.helvetica, 12),
    bounds: const Rect.fromLTWH(465, 40, 0, 0));

page.graphics.drawString(ChangeValue.companyAddress3Line,
    PdfStandardFont(PdfFontFamily.helvetica, 12),
    bounds: const Rect.fromLTWH(485, 60, 0, 0));

page.graphics.drawString(ChangeValue.companyAddress4Line,
    PdfStandardFont(PdfFontFamily.helvetica, 12),
    bounds: const Rect.fromLTWH(465, 80, 0, 0));

page.graphics.drawString('Tel: ${ChangeValue.companyTelPhone}',
    PdfStandardFont(PdfFontFamily.helvetica, 12),
    bounds: const Rect.fromLTWH(410, 100, 0, 0));

page.graphics.drawString(
    '____________________________________________________________________________',
    PdfStandardFont(PdfFontFamily.helvetica, 12),
    bounds: const Rect.fromLTWH(0, 130, 0, 0));

page.graphics.drawString("BILL TO :",
    PdfStandardFont(PdfFontFamily.helvetica, 12, style: PdfFontStyle.bold),
    bounds: const Rect.fromLTWH(0, 150, 0, 0));

page.graphics.drawString("$customerName",
    PdfStandardFont(PdfFontFamily.helvetica, 14, style: PdfFontStyle.bold),
    bounds: const Rect.fromLTWH(0, 170, 0, 0));

page.graphics.drawString("Address :", pdfStandardFont(),
    bounds: const Rect.fromLTWH(0, 190, 0, 0));

page.graphics.drawString("$address", pdfStandardFont(),
    bounds: const Rect.fromLTWH(55, 190, 0, 0));

page.graphics.drawString("City : ", pdfStandardFont(),
    bounds: const Rect.fromLTWH(0, 210, 0, 0));

page.graphics.drawString("$city", pdfStandardFont(),
    bounds: const Rect.fromLTWH(55, 210, 0, 0));

page.graphics.drawString("Country : ", pdfStandardFont(),
    bounds: const Rect.fromLTWH(0, 230, 0, 0));

page.graphics.drawString("$country", pdfStandardFont(),
    bounds: const Rect.fromLTWH(55, 230, 0, 0));

page.graphics.drawString("Postal : ", pdfStandardFont(),
    bounds: const Rect.fromLTWH(0, 250, 0, 0));

page.graphics.drawString("INVOICE #",
    PdfStandardFont(PdfFontFamily.helvetica, 12, style: PdfFontStyle.bold),
    format: PdfStringFormat(alignment: PdfTextAlignment.right),
    brush: PdfBrushes.black,
    bounds: Rect.fromLTWH(pageSize.width - 10, 150, 0, 0));

page.graphics.drawString("$invoiceNo", pdfStandardFont(),
    format: PdfStringFormat(alignment: PdfTextAlignment.right),
    brush: PdfBrushes.black,
    bounds: Rect.fromLTWH(pageSize.width - 10, 170, 0, 0));

reference == null
    ? 0
    : page.graphics.drawString(
        "REF #",
        PdfStandardFont(PdfFontFamily.helvetica, 12,
            style: PdfFontStyle.bold),
        format: PdfStringFormat(alignment: PdfTextAlignment.right),
        brush: PdfBrushes.black,
        bounds: Rect.fromLTWH(pageSize.width - 10, 190, 0, 0));

reference == null
    ? 0
    : page.graphics.drawString(
        reference != null ? "$reference" : "", pdfStandardFont(),
        format: PdfStringFormat(alignment: PdfTextAlignment.right),
        brush: PdfBrushes.black,
        bounds: Rect.fromLTWH(pageSize.width - 10, 210, 0, 0));

page.graphics.drawString("INVOICE DATE",
    PdfStandardFont(PdfFontFamily.helvetica, 12, style: PdfFontStyle.bold),
    format: PdfStringFormat(alignment: PdfTextAlignment.right),
    brush: PdfBrushes.black,
    bounds: Rect.fromLTWH(
        pageSize.width - 10, reference == null ? 190 : 230, 0, 0));

page.graphics.drawString(invoiceDate, pdfStandardFont(),
    brush: PdfBrushes.black,
    format: PdfStringFormat(alignment: PdfTextAlignment.right),
    bounds: Rect.fromLTWH(
        pageSize.width - 10, reference == null ? 210 : 250, 0, 0));

page.graphics.drawString("INVOICE DUE DATE",
    PdfStandardFont(PdfFontFamily.helvetica, 12, style: PdfFontStyle.bold),
    format: PdfStringFormat(alignment: PdfTextAlignment.right),
    brush: PdfBrushes.black,
    bounds: Rect.fromLTWH(
        pageSize.width - 10, reference == null ? 230 : 270, 0, 0));

page.graphics.drawString(invoiceDueDate, pdfStandardFont(),
    format: PdfStringFormat(alignment: PdfTextAlignment.right),
    brush: PdfBrushes.black,
    bounds: Rect.fromLTWH(
        pageSize.width - 10, reference == null ? 250 : 290, 0, 0));

page.graphics.drawString(
    '_____________________________________________________________________________________________',
    PdfStandardFont(PdfFontFamily.helvetica, 10),
    bounds: Rect.fromLTWH(0, reference == null ? 270 : 300, 0, 0));

page.graphics.drawString(postalCode ?? "", pdfStandardFont(),
    bounds: const Rect.fromLTWH(50, 250, 0, 0));

grid.draw(
    page: page, bounds: Rect.fromLTWH(0, pageSize.height - 430, 0, 0));
page.graphics.drawString(
    '_______________________________'
    ''
    ''
    '______________________________________________________________',
    PdfStandardFont(PdfFontFamily.helvetica, 10),
    bounds: const Rect.fromLTWH(0, 800, 0, 0));
int pageCount = document.pages.count;
kLog(content: pageCount, title: "Pages");
final PdfPage lastPage = document.pages[pageCount - 1];
kLog(content: lastPage, title: "Pages");

lastPage.graphics.drawString("",
    PdfStandardFont(PdfFontFamily.helvetica, 12, style: PdfFontStyle.bold),
    bounds: const Rect.fromLTWH(0, 150, 0, 0));
lastPage.graphics.drawString(
  "NOTES : $notes",
  PdfStandardFont(PdfFontFamily.helvetica, 10, style: PdfFontStyle.bold),
  bounds: Rect.fromLTWH(
      0,
      lastPage.getClientSize().height - 100,
      lastPage.getClientSize().width - 150,
      lastPage.getClientSize().height),
);

lastPage.graphics.drawString(
  "TOTAL",
  PdfStandardFont(PdfFontFamily.helvetica, 10, style: PdfFontStyle.bold),
  format: PdfStringFormat(alignment: PdfTextAlignment.center),
  bounds: Rect.fromLTWH(450, page.getClientSize().height - 100, 0, 0),
);
lastPage.graphics.drawString(
  "£$amount",
  PdfStandardFont(PdfFontFamily.helvetica, 20, style: PdfFontStyle.bold),
  format: PdfStringFormat(alignment: PdfTextAlignment.center),
  bounds: Rect.fromLTWH(450, page.getClientSize().height - 85, 0, 0),
);
List<int> bytes = document.saveSync();
var string = "$invoiceNo";
final split = string.split('/');
isUpdate
    ? saveAndLaunchFile(
        bytes, '${split[0] + split[1] + split[2]}.pdf', isOpen)
    : saveAndLaunchFile(
        bytes,
        '${ChangeValue.companyShortName}${year.year}$invoiceNo.pdf',
        isOpen);
document.dispose();

}

PdfGrid getGrid(item) { final PdfGrid grid = PdfGrid();

grid.columns.add(count: 6);
final PdfGridRow headerRow = grid.headers.add(1)[0];
headerRow.style.backgroundBrush = PdfSolidBrush(PdfColor(0, 0, 0));
headerRow.style.textBrush = PdfBrushes.white;
headerRow.cells[0].value = 'DATE';
headerRow.cells[1].value = 'DESCRIPTION';
headerRow.cells[2].value = 'Minibus/Suv/Sedan';
headerRow.cells[3].value = 'QTY';
headerRow.cells[4].value = 'PRICE';
headerRow.cells[5].value = 'AMOUNT';
headerRow.cells[0].stringFormat.alignment = PdfTextAlignment.center;
headerRow.cells[1].stringFormat.alignment = PdfTextAlignment.center;
headerRow.cells[2].stringFormat.alignment = PdfTextAlignment.center;
headerRow.cells[3].stringFormat.alignment = PdfTextAlignment.center;
headerRow.cells[4].stringFormat.alignment = PdfTextAlignment.center;
headerRow.cells[5].stringFormat.alignment = PdfTextAlignment.center;

for (var i = 0; i < item.length; i++) {
  addProducts(
      convertDate(item[i].itemDate),
      "${item[i].minibusSuvSedan}",
      '${item[i].description}',
      "£${item[i].price}",
      "${item[i].quantity}",
      "£${item[i].amount}",
      grid);
}
// addProducts('', "", '', "", "", "", grid);
grid.applyBuiltInStyle(PdfGridBuiltInStyle.gridTable1Light);

grid.columns[1].width = 120;
grid.columns[2].width = 150;
grid.columns[3].width = 50;
for (int i = 0; i < headerRow.cells.count; i++) {
  headerRow.cells[i].style.cellPadding =
      PdfPaddings(bottom: 5, left: 5, right: 5, top: 5);
}
for (int i = 0; i < grid.rows.count; i++) {
  final PdfGridRow row = grid.rows[i];
  for (int j = 0; j < row.cells.count; j++) {
    final PdfGridCell cell = row.cells[j];
    if (j == 0) {
      cell.stringFormat.alignment = PdfTextAlignment.center;
    }
    cell.style.cellPadding =
        PdfPaddings(bottom: 5, left: 5, right: 5, top: 5);
  }
}

return grid;

}

void addProducts(String date, String minibus, String description, String price, String quantity, String amount, PdfGrid grid) { final PdfGridRow row = grid.rows.add(); row.cells[0].value = date; row.cells[1].value = description; row.cells[2].value = minibus; row.cells[3].value = quantity.toString(); row.cells[4].value = price.toString(); row.cells[5].value = amount.toString(); row.cells[0].stringFormat.alignment = PdfTextAlignment.center; row.cells[1].stringFormat.alignment = PdfTextAlignment.center; row.cells[2].stringFormat.alignment = PdfTextAlignment.center; row.cells[3].stringFormat.alignment = PdfTextAlignment.center; row.cells[4].stringFormat.alignment = PdfTextAlignment.center; row.cells[5].stringFormat.alignment = PdfTextAlignment.center; }

Future saveAndLaunchFile(bytes, String fileName, isOpen) async { final path = (await getExternalStorageDirectory())!.path; kLog(content: ">>>> $path"); final file = File('$path/$fileName'); await file.writeAsBytes(bytes, flush: true); kLog(content: "0000$isOpen >>> $path >>> $fileName"); isOpen ? OpenFilex.open('$path/$fileName') : Share.shareXFiles([XFile("$path/$fileName")]); }

String convertDate(String date) { DateTime parseDate = DateFormat("yyyy-MM-dd").parse(date); var inputDate = DateTime.parse(parseDate.toString()); var outputFormat = DateFormat('dd/MM/yyyy'); var outputDate = outputFormat.format(inputDate); return outputDate; } }

irfanajaffer commented 7 months ago

To meet your requirements, we have two options: either utilize a footer template for all pages or manually allocate space at the bottom of the table using PdfLayoutFormat.paginateBounds.

To add a footer template for all pages, kindly use the following UG documentation for reference, Headers and Footers in Flutter PDF library | Syncfusion

To manually allocate space at the bottom of the table, kindly use the below modified code snippet for reference,


//The paginate bounds is preserved in every page during pagination.

PdfLayoutFormat layoutFormat = PdfLayoutFormat(

     layoutType: PdfLayoutType.paginate,

     paginateBounds: Rect.fromLTWH(

         0, 0, page.getClientSize().width, page.getClientSize().height - 100));

 grid.draw(

     page: page,

     bounds: Rect.fromLTWH(0, pageSize.height - 430, 0, 0),

     format: layoutFormat);

To know more about working with PdfGrid, kindly use the following UG documentation, Tables in Flutter PDF library | Syncfusion