Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Erro ao gerar pdf em Flutter

Olá, estou criando um pdf de relatório de vendas. Quando tenho muitas vendas a tabela que estou utilizando não "quebra" para a outra página e assim mostra um erro "TooManyPagesException". Alguém por acaso já passou por esse erro?

pdf.addPage(
      pw.MultiPage(
        pageFormat: PdfPageFormat.a4,
        margin: const pw.EdgeInsets.all(24),
        build: (pw.Context context) {
          return [
            //outros widgets......................

            pw.Center(
              child: pw.Column(
                crossAxisAlignment: pw.CrossAxisAlignment.start,
                children: [
                  pw.TableHelper.fromTextArray(
                    headers: [
                      "Data e hora",
                      "Qtd. de itens",
                      "Forma de pagamento",
                      "Total da venda",
                      "Lucro"
                    ],
                    data: sales.map((sale) {
                      return [
                        sale.getSale()["date"],
                        _sumItens(products: sale.getSale()["products"]),
                        paymentForm(paymentForm: sale.getSale()["paymentForm"]),
                        Formatters().formatMoneyBRL(
                            value: sale.getSale()["total"]["total"]),
                        Formatters()
                            .formatMoneyBRL(value: sale.getSale()["profit"]),
                      ];
                    }).toList(),
                  ),
                ],
              ),
            ),
          ]; // Center
        },
      ),
    );

Estou usando pdf: ^3.10.7

2 respostas
solução!

Olá, Junior. Tudo bem?

Pelo que entendi, você está enfrentando um problema com a geração de PDFs no Flutter quando a quantidade de vendas é muito grande, certo? Isso está causando um erro "TooManyPagesException".

A biblioteca que você está utilizando, pdf: ^3.10.7, tem uma limitação no número de páginas que pode gerar. Esse erro "TooManyPagesException" geralmente ocorre quando o número de páginas excede essa limitação.

Uma possível solução seria dividir seus dados em várias tabelas menores em vez de uma única tabela grande. Isso pode evitar que o número de páginas exceda o limite.

Aqui está um exemplo de como você pode fazer isso:

pdf.addPage(
  pw.MultiPage(
    pageFormat: PdfPageFormat.a4,
    margin: const pw.EdgeInsets.all(24),
    build: (pw.Context context) {
      return sales.map((sale) {
        return pw.Center(
          child: pw.Column(
            crossAxisAlignment: pw.CrossAxisAlignment.start,
            children: [
              pw.TableHelper.fromTextArray(
                headers: [
                  "Data e hora",
                  "Qtd. de itens",
                  "Forma de pagamento",
                  "Total da venda",
                  "Lucro"
                ],
                data: [
                  [
                    sale.getSale()["date"],
                    _sumItens(products: sale.getSale()["products"]),
                    paymentForm(paymentForm: sale.getSale()["paymentForm"]),
                    Formatters().formatMoneyBRL(
                        value: sale.getSale()["total"]["total"]),
                    Formatters()
                        .formatMoneyBRL(value: sale.getSale()["profit"]),
                  ],
                ],
              ),
            ],
          ),
        );
      }).toList();
    },
  ),
);

Neste exemplo, cada venda é representada por uma tabela separada. Isso pode ajudar a evitar o erro "TooManyPagesException", pois cada tabela é menor e requer menos páginas.

Espero ter entendido e conseguido ajudar. Qualquer dúvida pode mandar aqui de novo. Bons estudos!

Mas como posso adicionar outros widgets antes dele? O método completo:

Future<Uint8List> getPdf() async {
    List<Sale> sales = report.getSales();

    final pdf = pw.Document();

    final ByteData logoByte =
        await rootBundle.load('images/logo/logo_apollo_pdv.png');
    final Uint8List logo = logoByte.buffer.asUint8List();

    pdf.addPage(
      pw.MultiPage(
        pageFormat: PdfPageFormat.a4,
        margin: const pw.EdgeInsets.all(24),
        build: (pw.Context context) {
          return [
            pw.Center(
              child: pw.Column(
                crossAxisAlignment: pw.CrossAxisAlignment.start,
                children: [
                  pw.Column(
                      crossAxisAlignment: pw.CrossAxisAlignment.start,
                      children: [
                        pw.Text(
                          company.getName(),
                          style: pw.TextStyle(
                              fontSize: 12, fontWeight: pw.FontWeight.bold),
                        ),
                        pw.Text(
                          "${company.getAddress()["street"]},${company.getAddress()["number"]}, B. ${company.getAddress()["neighborhood"]}. ${company.getAddress()["city"]} - ${company.getAddress()["uf"]}",
                          style: pw.TextStyle(
                            fontSize: 8,
                            fontWeight: pw.FontWeight.normal,
                          ),
                        ),
                        pw.Padding(
                          padding: const pw.EdgeInsets.only(top: 4),
                          child: pw.Text(
                            "Contato: ${company.getPhone()}",
                            style: pw.TextStyle(
                              fontSize: 8,
                              fontWeight: pw.FontWeight.normal,
                            ),
                          ),
                        ),
                        pw.Text(
                          "CNPJ: ${company.getCNPJ()}",
                          style: pw.TextStyle(
                            fontSize: 8,
                            fontWeight: pw.FontWeight.normal,
                          ),
                        ),
                      ]),
                  pw.Column(
                      mainAxisAlignment: pw.MainAxisAlignment.center,
                      children: [
                        pw.Divider(thickness: 0.4),
                        pw.Text(
                          "RELATÓRIO DE VENDAS",
                          style: pw.TextStyle(
                            fontSize: 12,
                            fontWeight: pw.FontWeight.bold,
                          ),
                        ),
                        pw.Divider(thickness: 0.4),
                      ]),
                  pw.Text(
                    "RESUMO DAS VENDAS",
                    style: pw.TextStyle(
                      fontSize: 12,
                      fontWeight: pw.FontWeight.bold,
                    ),
                  ),
                  pw.TableHelper.fromTextArray(
                    headers: [
                      "Data e hora",
                      "Qtd. de itens",
                      "Forma de pagamento",
                      "Total da venda",
                      "Lucro"
                    ],
                    data: sales.map((sale) {
                      return [
                        sale.getSale()["date"],
                        _sumItens(products: sale.getSale()["products"]),
                        paymentForm(paymentForm: sale.getSale()["paymentForm"]),
                        Formatters().formatMoneyBRL(
                            value: sale.getSale()["total"]["total"]),
                        Formatters()
                            .formatMoneyBRL(value: sale.getSale()["profit"]),
                      ];
                    }).toList(),
                  ),
                ],
              ),
            ),
          ]; // Center
        },
        footer: (context) => pw.Column(
          children: [
            pw.Padding(
              padding: const pw.EdgeInsets.only(bottom: 8),
              child: pw.Divider(thickness: 0.4),
            ),
            pw.Row(
              mainAxisAlignment: pw.MainAxisAlignment.center,
              children: [
                pw.Image(
                  pw.MemoryImage(logo),
                  height: 16,
                  fit: pw.BoxFit.contain,
                ),
              ],
            ),
          ],
        ),
      ),
    );
    return pdf.save();
  }