📜  Flutter – 简单的 PDF 生成应用

📅  最后修改于: 2021-09-02 05:32:47             🧑  作者: Mango

Flutter社区创建了几个包来在我们的应用程序中处理 PDF。在本文中,我们将创建一个简单的 PDF 生成应用程序。此应用程序将纯文本转换为 PDF。下面列出了我们将需要的软件包及其用途:

  • pdf:它是一个flutter的 PDF 创建库。它可以创建包含图像、表格、不同字体等的完整多页文档。
  • flutter_full_pdf_viewer:用于预览PDF。
  • path_provider:用于查找文件系统上常用的位置。

现在让我们做一些编码。

首先,我们必须在pubspec.yaml 文件的依赖项部分安装必要的包,如下所示:

pubspec.yaml ss

1. PDF 预览屏幕页面:

现在,包第一次安装,我们要创建PDF预览画面作为新dart文件(pdf_preview_screendart)给定的路径如下图所示:

Dart
import 'package:flutter/material.dart';
import 'package:flutter_full_pdf_viewer/flutter_full_pdf_viewer.dart';
  
class PdfPreviewScreen extends StatelessWidget {
  final String path;
  
  PdfPreviewScreen({this.path});
  
  @override
  Widget build(BuildContext context) {
    return PDFViewerScaffold(
      path: path,
    );
  }
}


Dart
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pw;
import 'package:pdf_demo/pdf_preview_screen.dart';


Dart
void main() {
  runApp(MyApp());
}
  
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'PDF Demo',
      theme: ThemeData(
        primarySwatch: Colors.grey,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(),
    );
  }
}


Dart
class MyHomePage extends StatelessWidget {
  final pdf = pw.Document();
  
  writeOnPdf() {
    pdf.addPage(pw.MultiPage(
      pageFormat: PdfPageFormat.a4,
      margin: pw.EdgeInsets.all(32),
      build: (pw.Context context) {
        return [
          pw.Header(
              level: 0,
              child: pw.Row(
                  mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
                  children: [
                    pw.Text('Geeksforgeeks', textScaleFactor: 2),
                  ])),
          pw.Header(level: 1, text: 'What is Lorem Ipsum?'),
            
          // Write All the paragraph in one line. 
          // For clear understanding
          // here there are line breaks.
          pw.Paragraph(
              text:
                  'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
                  tempor incididunt ut labore et dolore magna aliqua. Nunc mi ipsum faucibus
                  vitae aliquet nec. Nibh cras pulvinar mattis nunc sed blandit libero
                  volutpat. Vitae elementum curabitur vitae nunc sed velit. Nibh tellus
                  molestie nunc non blandit massa. Bibendum enim facilisis gravida neque.
                  Arcu cursus euismod quis viverra nibh cras pulvinar mattis. Enim diam
                  vulputate ut pharetra sit. Tellus pellentesque eu tincidunt tortor
                  aliquam nulla facilisi cras fermentum. '),
          pw.Paragraph(
              text:
                  'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
                  tempor incididunt ut labore et dolore magna aliqua. Nunc mi ipsum faucibus
                  vitae aliquet nec. Nibh cras pulvinar mattis nunc sed blandit libero
                  volutpat Vitae elementum curabitur vitae nunc sed velit. Nibh tellus
                  molestie nunc non blandit massa. Bibendum enim facilisis gravida neque.
                  Arcu cursus euismod quis viverra nibh cras pulvinar mattis. Enim diam
                  vulputate ut pharetra sit. Tellus pellentesque eu tincidunt tortor
                  aliquam nulla facilisi cras fermentum. '),
          pw.Header(level: 1, text: 'This is Header'),
          pw.Paragraph(
              text:
                  'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
                  tempor incididunt ut labore et dolore magna aliqua. Nunc mi ipsum faucibus
                  vitae aliquet nec. Nibh cras pulvinar mattis nunc sed blandit libero
                  volutpat. Vitae elementum curabitur vitae nunc sed velit. Nibh tellus
                  molestie nunc non blandit massa. Bibendum enim facilisis gravida neque.
                  Arcu cursus euismod quis viverra nibh cras pulvinar mattis. Enim diam
                  vulputate ut pharetra sit. Tellus pellentesque eu tincidunt tortor aliquam
                  nulla facilisi cras fermentum. Consectetur adipiscing elit duis tristique
                  sollicitudin nibh sit. '),
          pw.Paragraph(
              text:
                  'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
                  tempor incididunt ut labore et dolore magna aliqua. Nunc mi ipsum faucibus
                  vitae aliquet nec. Nibh cras pulvinar mattis nunc sed blandit libero
                  volutpat. Vitae elementum curabitur vitae nunc sed velit. Nibh tellus
                  molestie nunc non blandit massa. Bibendum enim facilisis gravida neque.
                  Arcu cursus euismod quis viverra nibh cras pulvinar mattis. Enim diam
                  vulputate ut pharetra sit. Tellus pellentesque eu tincidunt tortor aliquam
                  nulla facilisi cras fermentum. Consectetur adipiscing elit duis tristique
                  sollicitudin nibh sit. '),
          pw.Padding(padding: const pw.EdgeInsets.all(10)),
          pw.Table.fromTextArray(context: context, data: const >[
            ['Year', 'Sample'],
            ['SN0', 'GFG1'],
            ['SN1', 'GFG2'],
            ['SN2', 'GFG3'],
            ['SN3', 'GFG4'],
          ]),
        ];
      },
    ));
  }


Dart
Future savePdf() async {
    Directory documentDirectory = await getApplicationDocumentsDirectory();
    String documentPath = documentDirectory.path;
    File file = File("$documentPath/example.pdf");
    file.writeAsBytesSync(pdf.save());
  }


Dart
Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Geeksforgeeks"),
      ),
      body: Container(
        padding: EdgeInsets.all(10),
        child: Column(
          children: [
            SizedBox(
              width: double.infinity,
              child: RaisedButton(
                color: Colors.blueGrey,
                child: Text(
                  'Preview PDF',
                  style: TextStyle(
                      fontWeight: FontWeight.bold,
                      fontSize: 18,
                      color: Colors.white),
                ),
                onPressed: () async {
                  writeOnPdf();
                  await savePdf();
  
                  Directory documentDirectory =
                      await getApplicationDocumentsDirectory();
  
                  String documentPath = documentDirectory.path;
  
                  String fullPath = "$documentPath/example.pdf";
                  print(fullPath);
  
                  Navigator.push(
                      context,
                      MaterialPageRoute(
                          builder: (context) => PdfPreviewScreen(
                                path: fullPath,
                              )));
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}


在此页面中,我们以 PDF 文件的路径作为参数创建了PDFPreviewScreen作为StatelessWidget

2. 主页:

我们已经导入了创建所需布局所需的包。这里我们导入了 ‘ package:pdf/widgets. dart ‘ as pw因为材料包已经有一个小部件类。

Dart

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pw;
import 'package:pdf_demo/pdf_preview_screen.dart';

这是应用程序启动时调用的主要函数

Dart

void main() {
  runApp(MyApp());
}
  
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'PDF Demo',
      theme: ThemeData(
        primarySwatch: Colors.grey,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(),
    );
  }
}

来自 pdf 的小部件包具有用于创建所需布局的不同类型的小部件。 MyHomePage()是一个StatelessWidget ,它包含创建 PDF 的代码。现在我们要向应用程序添加内容。为此,我们将创建一个函数writeOnPdf()

Dart

class MyHomePage extends StatelessWidget {
  final pdf = pw.Document();
  
  writeOnPdf() {
    pdf.addPage(pw.MultiPage(
      pageFormat: PdfPageFormat.a4,
      margin: pw.EdgeInsets.all(32),
      build: (pw.Context context) {
        return [
          pw.Header(
              level: 0,
              child: pw.Row(
                  mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
                  children: [
                    pw.Text('Geeksforgeeks', textScaleFactor: 2),
                  ])),
          pw.Header(level: 1, text: 'What is Lorem Ipsum?'),
            
          // Write All the paragraph in one line. 
          // For clear understanding
          // here there are line breaks.
          pw.Paragraph(
              text:
                  'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
                  tempor incididunt ut labore et dolore magna aliqua. Nunc mi ipsum faucibus
                  vitae aliquet nec. Nibh cras pulvinar mattis nunc sed blandit libero
                  volutpat. Vitae elementum curabitur vitae nunc sed velit. Nibh tellus
                  molestie nunc non blandit massa. Bibendum enim facilisis gravida neque.
                  Arcu cursus euismod quis viverra nibh cras pulvinar mattis. Enim diam
                  vulputate ut pharetra sit. Tellus pellentesque eu tincidunt tortor
                  aliquam nulla facilisi cras fermentum. '),
          pw.Paragraph(
              text:
                  'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
                  tempor incididunt ut labore et dolore magna aliqua. Nunc mi ipsum faucibus
                  vitae aliquet nec. Nibh cras pulvinar mattis nunc sed blandit libero
                  volutpat Vitae elementum curabitur vitae nunc sed velit. Nibh tellus
                  molestie nunc non blandit massa. Bibendum enim facilisis gravida neque.
                  Arcu cursus euismod quis viverra nibh cras pulvinar mattis. Enim diam
                  vulputate ut pharetra sit. Tellus pellentesque eu tincidunt tortor
                  aliquam nulla facilisi cras fermentum. '),
          pw.Header(level: 1, text: 'This is Header'),
          pw.Paragraph(
              text:
                  'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
                  tempor incididunt ut labore et dolore magna aliqua. Nunc mi ipsum faucibus
                  vitae aliquet nec. Nibh cras pulvinar mattis nunc sed blandit libero
                  volutpat. Vitae elementum curabitur vitae nunc sed velit. Nibh tellus
                  molestie nunc non blandit massa. Bibendum enim facilisis gravida neque.
                  Arcu cursus euismod quis viverra nibh cras pulvinar mattis. Enim diam
                  vulputate ut pharetra sit. Tellus pellentesque eu tincidunt tortor aliquam
                  nulla facilisi cras fermentum. Consectetur adipiscing elit duis tristique
                  sollicitudin nibh sit. '),
          pw.Paragraph(
              text:
                  'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
                  tempor incididunt ut labore et dolore magna aliqua. Nunc mi ipsum faucibus
                  vitae aliquet nec. Nibh cras pulvinar mattis nunc sed blandit libero
                  volutpat. Vitae elementum curabitur vitae nunc sed velit. Nibh tellus
                  molestie nunc non blandit massa. Bibendum enim facilisis gravida neque.
                  Arcu cursus euismod quis viverra nibh cras pulvinar mattis. Enim diam
                  vulputate ut pharetra sit. Tellus pellentesque eu tincidunt tortor aliquam
                  nulla facilisi cras fermentum. Consectetur adipiscing elit duis tristique
                  sollicitudin nibh sit. '),
          pw.Padding(padding: const pw.EdgeInsets.all(10)),
          pw.Table.fromTextArray(context: context, data: const >[
            ['Year', 'Sample'],
            ['SN0', 'GFG1'],
            ['SN1', 'GFG2'],
            ['SN2', 'GFG3'],
            ['SN3', 'GFG4'],
          ]),
        ];
      },
    ));
  }

此包中可用的小部件与材料包中可用的小部件不同。它们用于构建文档的布局。在这里,我们创建了带有一些标题、段落和表格的文档,以展示如何创建基本结构。

Dart

Future savePdf() async {
    Directory documentDirectory = await getApplicationDocumentsDirectory();
    String documentPath = documentDirectory.path;
    File file = File("$documentPath/example.pdf");
    file.writeAsBytesSync(pdf.save());
  }

savePdf()函数用于保存 PDF,稍后用于从提供的路径预览文档。编写上述代码行后,我们必须重新运行应用程序。

上面下面的代码是我们运行应用程序后得到的屏幕。它包含一个应用栏和一个凸起的按钮,用于生成和预览我们通过编写上述代码行创建的 PDF。我们将异步函数传递给按钮的onPressed参数,因为需要文件位置,它返回保存文件时已存储的未来。这也是MyHomePage类的结束。

Dart

Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Geeksforgeeks"),
      ),
      body: Container(
        padding: EdgeInsets.all(10),
        child: Column(
          children: [
            SizedBox(
              width: double.infinity,
              child: RaisedButton(
                color: Colors.blueGrey,
                child: Text(
                  'Preview PDF',
                  style: TextStyle(
                      fontWeight: FontWeight.bold,
                      fontSize: 18,
                      color: Colors.white),
                ),
                onPressed: () async {
                  writeOnPdf();
                  await savePdf();
  
                  Directory documentDirectory =
                      await getApplicationDocumentsDirectory();
  
                  String documentPath = documentDirectory.path;
  
                  String fullPath = "$documentPath/example.pdf";
                  print(fullPath);
  
                  Navigator.push(
                      context,
                      MaterialPageRoute(
                          builder: (context) => PdfPreviewScreen(
                                path: fullPath,
                              )));
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}

输出:

想要一个更快节奏和更具竞争力的环境来学习 Android 的基础知识吗?
单击此处前往由我们的专家精心策划的指南,旨在让您立即做好行业准备!