flutterprinting

Flutter Printing Library (Flutter Web): How can I give a name of my own choice to a PDF shown in the browser print preview?


I am using the printing library in Flutter to show a PDF preview. It causes the default browser dialog to show up, and I have an option to save the PDF to my machine. When I save it to my machine, following is the name of the file:

Name of the PDF file

I want to give it a name of my own choice. So far this is what I have tried:

  1. Set the 'name' parameter in Printing.layoutPDF (The result is still the same)
  2. Tried using Printing.sharePDF and setting the filename parameter inside it. (I get my desired name, but this gets rid of the print preview, which I do not want).

The next solution that comes to my mind is to create a custom print preview and give a download option to the user that uses Printing.sharePDF under the hood.

I am asking here to know if there is perhaps a simpler solution to this problem that I am missing that will allow me to set the name when I press the browser print button.

Sample code that reproduces this problem is as follows. I am running this on Google Chrome:

import 'package:flutter/material.dart';
import 'package:printing/printing.dart';
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pw;

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});
  
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Print Preview Demo',
      home: const PrintPreviewPage(),
    );
  }
}

class PrintPreviewPage extends StatelessWidget {
  const PrintPreviewPage({super.key});

  Future<void> _printDocument() async {
    final pdf = pw.Document();

    pdf.addPage(
      pw.Page(
        build: (pw.Context context) => pw.Center(
          child: pw.Text('Hello, Flutter Print!'),
        ),
      ),
    );

    await Printing.layoutPdf(
      name:'my_pdf.pdf', //This is what I have tried (option 1)
      onLayout: (PdfPageFormat format) async => pdf.save(),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Print Preview Demo')),
      body: Center(
        child: ElevatedButton(
          onPressed: _printDocument,
          child: const Text('Print Preview'),
        ),
      ),
    );
  }
}


Solution

  • Based on the comment from @K J, I updated my code as follows:

    import 'package:flutter/material.dart';
    import 'package:printing/printing.dart';
    import 'package:pdf/pdf.dart';
    import 'package:pdf/widgets.dart' as pw;
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
      
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Print Preview Demo',
          home: const PrintPreviewPage(),
        );
      }
    }
    
    class PrintPreviewPage extends StatelessWidget {
      const PrintPreviewPage({super.key});
    
      Future<void> _printDocument() async {
        final pdf = pw.Document(title:'my_pdf.pdf'); //I changed this line to my preferred name.
        pdf.addPage(
          pw.Page(
            build: (pw.Context context) => pw.Center(
              child: pw.Text('Hello, Flutter Print!'),
            ),
          ),
        );
    
        await Printing.layoutPdf( //This is what I have tried.
          onLayout: (PdfPageFormat format) async => pdf.save(),
        );
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: const Text('Print Preview Demo')),
          body: Center(
            child: ElevatedButton(
              onPressed: _printDocument,
              child: const Text('Print Preview'),
            ),
          ),
        );
      }
    }
    

    Now, when I save the pdf using the browser dialog in Google Chrome, this is the name I get:

    enter image description here

    I hope this will help someone who faces a similar problem in the future.