DavBfr / dart_pdf

Pdf creation module for dart/flutter
https://pub.dev/packages/pdf
Apache License 2.0
1.42k stars 633 forks source link

Rows with less columns automatically change to larger amount of columns #82

Closed liveaffiliates closed 5 years ago

liveaffiliates commented 5 years ago

Describe the bug If the row below has less columns than the row above, extra columns are added to the row below .

To Reproduce

`Pdf.Table (border: Pdf.TableBorder(

                      ),
                      children: <Pdf.TableRow>[

                        Pdf.TableRow(
                            children: <Pdf.Widget>[
                              Pdf.Container(
                                width: 4,
                                height: 30,
                                child: Pdf.Align(alignment: Pdf.Alignment.centerLeft, child: Pdf.Text('  Doc Ref Code:', textAlign: Pdf.TextAlign.left, style: Pdf.TextStyle(fontWeight: Pdf.FontWeight.bold, fontSize: 12)),),
                              ),

                              Pdf.Container(
                                width: 5,
                                height: 30,
                                 child: Pdf.Align(alignment: Pdf.Alignment.centerLeft, child: Pdf.Text('', textAlign: Pdf.TextAlign.left, style: Pdf.TextStyle(fontWeight: Pdf.FontWeight.bold, fontSize: 12)),),
                              ),

                              Pdf.Container(
                                width: 4,
                                height: 30,
                                child: Pdf.Align(alignment: Pdf.Alignment.centerLeft, child: Pdf.Text('  Last Review Date:', textAlign: Pdf.TextAlign.left, style: Pdf.TextStyle(fontWeight: Pdf.FontWeight.bold, fontSize: 12)),),
                              ),

                              Pdf.Container(
                                width: 2.5,
                                height: 30,
                                child: Pdf.Align(alignment: Pdf.Alignment.centerLeft, child: Pdf.Text('', textAlign: Pdf.TextAlign.left, style: Pdf.TextStyle(fontWeight: Pdf.FontWeight.bold, fontSize: 12)),),
                              ),

                              Pdf.Container(
                                width: 5,
                                height: 30,
                                child: Pdf.Align(alignment: Pdf.Alignment.centerLeft, child: Pdf.Text('  Applicable Location (s)', textAlign: Pdf.TextAlign.left, style: Pdf.TextStyle(fontWeight: Pdf.FontWeight.bold, fontSize: 12)),),
                              ),

                              Pdf.Container(
                                width: 2.5,
                                height: 30,
                                child: Pdf.Align(alignment: Pdf.Alignment.centerLeft, child: Pdf.Text('', textAlign: Pdf.TextAlign.left, style: Pdf.TextStyle(fontWeight: Pdf.FontWeight.bold, fontSize: 12)),),
                              ),

                            ]
                        ),

                        Pdf.TableRow(
                            children: <Pdf.Widget>[
                              Pdf.Container(
                                width: 4,
                                height: 30,
                                child: Pdf.Align(alignment: Pdf.Alignment.centerLeft, child: Pdf.Text('  SAP Func Loc:', textAlign: Pdf.TextAlign.left, style: Pdf.TextStyle(fontWeight: Pdf.FontWeight.bold, fontSize: 12)),),
                              ),

                              Pdf.Container(
                                color: PdfColors.grey,
                                width: 5,
                                height: 30,
                                child: Pdf.Align(alignment: Pdf.Alignment.centerLeft, child: Pdf.Text('', textAlign: Pdf.TextAlign.left, style: Pdf.TextStyle(fontWeight: Pdf.FontWeight.bold, fontSize: 12)),),
                              ),

                              Pdf.Container(
                                width: 4,
                                height: 30,
                                child: Pdf.Align(alignment: Pdf.Alignment.centerLeft, child: Pdf.Text('  Department:', textAlign: Pdf.TextAlign.left, style: Pdf.TextStyle(fontWeight: Pdf.FontWeight.bold, fontSize: 12)),),
                              ),

                              Pdf.Container(
                                width: 9.5,
                                height: 30,
                                child: Pdf.Align(alignment: Pdf.Alignment.centerLeft, child: Pdf.Text('', textAlign: Pdf.TextAlign.left, style: Pdf.TextStyle(fontWeight: Pdf.FontWeight.bold, fontSize: 12)),),
                              ),

                            ]
                        ),

                      ]),`

Expected behavior If there are 6 columns on the top row and 4 columns on the second row but the containers are sized to make both rows the exact same width. Then no extra rows are added.

Screenshots If applicable, add screenshots to help explain your problem.

DavBfr commented 5 years ago

If you take your code and execute on Flutter, using the Flutter Widgets, it crashes because the rows are not the same:

Table contains irregular row lengths. Every TableRow in a Table must have the same number of children, so that every cell is filled. Otherwise, the table will contain holes.

So I guess the Pdf version should do the same.

liveaffiliates commented 5 years ago

Ok, thanks. It doesn't crash it just adds the extra columns.

insinfo commented 5 months ago

@DavBfr
Is there any way to merge cells? So that it is possible to do this

image

image image

insinfo commented 5 months ago

I got an approximate result with this code below but I don't know if it's ideal or the best way to do this.

@liveaffiliates Did you find any way to do this? I think the ideal would be the TableRow class, since I already had the implementation of colspan and rowspan

import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart';

import 'package:sibem_frontend/sibem_frontend.dart';

class VisaoGeralVagaPdfService {
  final labelStyle = TextStyle(fontSize: 8);
  final valueStyle = TextStyle(fontSize: 10, fontWeight: FontWeight.bold);

  Widget buildRowCustom(
    Map<String, dynamic> labelValue,
  ) {
    final children = <Widget>[];

    final items = labelValue.entries.toList();
    final itemsCount = items.length;

    for (var i = 0; i < itemsCount; i++) {
      final label = items[i].key;
      final itemVal = items[i].value;

      var value = itemVal;
      if (value is bool) {
        value = value == true ? 'Sim' : 'Não';
      }
      bool isLast = i == itemsCount - 1;
      bool isFirst = i == 0;

      double? width;
      if (isLast && itemsCount != 1) {
        width = 200;
      } else {
        width = null;
      }

      children.add(
        Container(
          decoration: BoxDecoration(
            border: Border(left: isFirst ? BorderSide.none : BorderSide()),
          ),
          child: Column(
              mainAxisSize: MainAxisSize.min,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Container(
                    width: width,
                    alignment: Alignment.topLeft,
                    padding: EdgeInsets.fromLTRB(10, 5, 10, 0),
                    child: Text(label.toUpperCase(), style: labelStyle)),
                Container(
                    width: width,
                    alignment: Alignment.topLeft,
                    padding: EdgeInsets.fromLTRB(10, 2, 10, 5),
                    child: Text(value?.toString() ?? 'Não definido',
                        style: valueStyle)),
              ]),
        ),
      );
    }

    return Container(
        decoration: BoxDecoration(
          border: Border(bottom: BorderSide()),
        ),
        child: Flex(
            direction: Axis.horizontal,
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            mainAxisSize: MainAxisSize.max,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: children));
  }

  Future<void> generate(Vaga vagaSel) async {
    final docPdf = Document();

    final header = await PdfHeader.gen();

    docPdf.addPage(
      MultiPage(
          maxPages: 1000,
          orientation: PageOrientation.portrait,
          pageFormat: PdfPageFormat.a4.copyWith(
            marginTop: 1.0 * PdfPageFormat.cm,
            marginLeft: 1.0 * PdfPageFormat.cm,
            marginRight: 1.0 * PdfPageFormat.cm,
            marginBottom: 1.0 * PdfPageFormat.cm,
          ),
          crossAxisAlignment: CrossAxisAlignment.start,
          header: (Context context) {
            return header;
          },
          build: (Context context) {
            final widgets = <Widget>[
              // table 1
              Container(
                decoration: BoxDecoration(
                  border: Border.all(),
                ),
                child: Column(children: [
                  buildRowCustom({
                    'EMPREGADOR:': vagaSel.empregador?.nome,
                    'CNPJ/CPF:': vagaSel.empregador?.cpfOrCnpjFormatado
                  }),
                  buildRowCustom({
                    'NOME FANTASIA:':
                        vagaSel.empregador?.pessoaJuridica?.nomeFantasia,
                    'CADASTRADO:':
                        vagaSel.empregador?.dataCadastroEmpregadorFormatado
                  }),
                  buildRowCustom({
                    'CONTATO:': vagaSel.empregador?.contato,
                    'CADASTRADO:':
                        vagaSel.empregador?.dataCadastroEmpregadorFormatado
                  }),
                  buildRowCustom({
                    'E-MAIL:': vagaSel.empregador?.emailPrincipal,
                    'TELEFONES:': vagaSel.empregador?.telefones
                        .map((te) => te.numeroFormatado)
                        .join(', ')
                  }),
                  buildRowCustom(
                      {'OBSERVAÇÃO:': vagaSel.empregador?.observacao}),
                ]),
              ),
              //
              SizedBox(height: 15, width: 15),
              // table 2
              Container(
                decoration: BoxDecoration(
                  border: Border.all(),
                ),
                child: Column(children: [
                  buildRowCustom({'CARGO:': vagaSel.cargoNome}),
                ]),
              ),
              //
              SizedBox(height: 15, width: 15),
              // table 3
              Container(
                decoration: BoxDecoration(
                  border: Border.all(),
                ),
                child: Column(children: [
                  buildRowCustom({
                    'ABERTURA:': vagaSel.dataAberturaFormatada,
                    'ENCERRAMENTO:': vagaSel.dataEncerramentoFormatada,
                    'Nº VAGAS:': vagaSel.numeroVagas,
                  }),
                  buildRowCustom({
                    'MÁXIMO DE ENCAMINHAMENTOS:': vagaSel.numeroEncaminhamentos,
                    'IDADE MÍNIMA:': vagaSel.idadeMinima,
                    'IDADE Maxima:': vagaSel.idadeMinima,
                  }),
                  buildRowCustom({
                    'SEXO BIOLÓGICO:': vagaSel.sexoBiologico,
                    'IDENTIDADE DE GÊNERO:': vagaSel.identidadeGenero,
                    'Vaga PCD:': vagaSel.vagaPcd,
                  }),
                  buildRowCustom({
                    'Aceita Fumante:': vagaSel.aceitaFumante,
                    'Escolaridade exigida:': vagaSel.grauEscolaridade,
                    'Tipo da Vaga:': vagaSel.tipoVaga
                  }),
                  buildRowCustom({
                    'Salario:': vagaSel.salario,
                    'TURNO:': vagaSel.turno,
                    'CARGA HORARIA SEMANAL:': vagaSel.cargaHorariaSemanal,
                  }),
                  buildRowCustom({
                    'Escala:': vagaSel.escala,
                    'Expediente:': vagaSel.descricaoCargaHoraria,
                    'Área Petróleo e Gás': vagaSel.areaPetroleoGas
                  }),
                  buildRowCustom({
                    'OffShore:': vagaSel.offShore,
                    'Habilitação exigida:': vagaSel.categoriaHabilitacao,
                  }),
                  buildRowCustom({
                    'Contato de Encaminhamento:': vagaSel.offShore,
                    'Forma Encaminhamento:': vagaSel.formaEncaminhamento,
                  }),
                  buildRowCustom({
                    'Complemento Forma de Encaminhamento:':
                        vagaSel.complementoFormaEncaminhamento,
                  }),
                ]),
              ),
            ];

            return widgets;
          }),
    );

    //save PDF
    final bytes = await docPdf.save();

    //FrontUtils.download(bytes, 'application/pdf', 'Relatório.pdf');
    await FrontUtils.printFileBytes(bytes, 'application/pdf');
  }
}

image