Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I create a PDF file in flutter after doing some math on a JSON response?

Hello I've brainstormed this enough & I'd like to get some advise here.. Coming straight to the point :

Here's my Json response body through Flutter Async :

{

  "success":true,"data":

 [ 
    {"id":161,
     "product_name":"Apple",
     "user_id":72,
     "quantity":1,
     "price": 96
     "custom_fields":[]
    },
    
    {"id":162,
     "product_name":"Orange",
     "user_id":72,
     "quantity":2,
     "price": 85,
     "custom_fields":[]
    }
 ],
 
  "message":"Carts retrieved successfully"

}

I need to be able to create a PDF file within flutter using the array above & the content of the PDF file should look like :

    XXXXXX

    Item    Qty  price 

  1)Apple   1    96
  2)Orange  2    170
  
  Subtotal : 266

Finally i''m going to send this PDF to my PHP server(Can use some packages for this). I'd need some expert advise if this requirement is feasible & some help to get started.

like image 544
Adrian Karr Avatar asked Jan 25 '23 19:01

Adrian Karr


1 Answers

This is the data class for your json

 class ModelClass {
  bool success;
  List<Data> data;
  String message;

  ModelClass({this.success, this.data, this.message});

  ModelClass.fromJson(Map<String, dynamic> json) {
    success = json['success'];
    if (json['data'] != null) {
      data = new List<Data>();
      json['data'].forEach((v) {
        data.add(new Data.fromJson(v));
      });
    }
    message = json['message'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['success'] = this.success;
    if (this.data != null) {
      data['data'] = this.data.map((v) => v.toJson()).toList();
    }
    data['message'] = this.message;
    return data;
  }
}

class Data {
  int id;
  String productName;
  int userId;
  int quantity;
  int price;
  List<dynamic> customFields;

  Data(
      {this.id,
        this.productName,
        this.userId,
        this.quantity,
        this.price,
        this.customFields});

  Data.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    productName = json['product_name'];
    userId = json['user_id'];
    quantity = json['quantity'];
    price = json['price'];
    customFields = json['custom_fields'].cast<String>();
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['id'] = this.id;
    data['product_name'] = this.productName;
    data['user_id'] = this.userId;
    data['quantity'] = this.quantity;
    data['price'] = this.price;
    data['custom_fields'] = this.customFields;
    return data;
  }
}

Now parse the json in model object

ModelClass modelClass = ModelClass.fromJson(json);

Now by using pdf package we can build our pdf.

import 'dart:typed_data';
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pw;

Future<Uint8List> generateDocument() async {
  final pw.Document doc = pw.Document();
  
  doc.addPage(pw.MultiPage(
      pageFormat:
          PdfPageFormat.letter.copyWith(marginBottom: 1.5 * PdfPageFormat.cm),
      crossAxisAlignment: pw.CrossAxisAlignment.start,
      header: (pw.Context context) {
        if (context.pageNumber == 1) {
          return null;
        }
        return pw.Container(
            alignment: pw.Alignment.centerRight,
            margin: const pw.EdgeInsets.only(bottom: 3.0 * PdfPageFormat.mm),
            padding: const pw.EdgeInsets.only(bottom: 3.0 * PdfPageFormat.mm),
            decoration: const pw.BoxDecoration(
                border: pw.BoxBorder(
                    bottom: true, width: 0.5, color: PdfColors.grey)),
            child: pw.Text('Portable Document Format',
                style: pw.Theme.of(context)
                    .defaultTextStyle
                    .copyWith(color: PdfColors.grey)));
      },
      build: (pw.Context context) => <pw.Widget>[
            pw.Table.fromTextArray(
                context: context,
                border: null,
                headerAlignment: pw.Alignment.centerLeft,
                data: <List<String>>[
                  <String>['Item', 'Qty', 'Price'],
                  for (int i = 0; i < modelClass.data.length; i++)
                    <String>['${i+1}) ${modelClass.data.elementAt(i).productName}', '${modelClass.data.elementAt(i).quantity}', '${modelClass.data.elementAt(i).price}'],
                ]),
        pw.Paragraph(text: ""),
        pw.Paragraph(text: "Subtotal: $total"),
            pw.Padding(padding: const pw.EdgeInsets.all(10)),
          ]));

  return doc.save();
}

Now to view this pdf use flutter_pdfview package.

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  File file;

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: file!=null?PDFView(
          filePath: file.path,
          autoSpacing: false,
          pageFling: false,
        ):Container()
      ),
    );
  }

  @override
  void initState() {
    getPdf();
    super.initState();
  }

  void getPdf() async{
    Uint8List uint8list = await generateDocument();
    Directory output = await getTemporaryDirectory();
    file = File(output.path+"/example.pdf");
    setState(() {
      file.writeAsBytes(uint8list);
      print(file.path);
    });
  }

}

Output: Output

like image 137
Tipu Sultan Avatar answered May 12 '23 11:05

Tipu Sultan