如何在Flutter中创建PDF并进行审阅。

huangapple go评论96阅读模式
英文:

How to create pdf and review in flutter

问题

I'm trying to create pdf and review it.

我正在尝试创建 PDF 并查看它。

I applied pdf plugin for creating the pdf, path_provider plugin for save the pdf to the device's storage and flutter_full_pdf_viewer plugin for view the pdf.

我使用 pdf 插件创建 PDF,使用 path_provider 插件将 PDF 保存到设备存储中,使用 flutter_full_pdf_viewer 插件查看 PDF。

I have followed create-a-pdf-in-flutter.
But getting errors in the code if I try to import with import 'package:pdf/widgets.dart';, material element isn't working import 'package:flutter/material.dart';.

我遵循了 create-a-pdf-in-flutter。但是,如果我尝试导入 import 'package:pdf/widgets.dart';,代码会出现错误,Material 元素无法工作 import 'package:flutter/material.dart';

What am I doing wrong?

我做错了什么?

Code:

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:pdf/pdf.dart';
import 'package:path_provider/path_provider.dart';
import 'package:pdfdemo/pages/pdf_viewer.dart';
//import 'package:pdf/widgets.dart'

Variable:

final pdf = Document();

Creating pdf file page:

return Scaffold(
      appBar: AppBar(title: Text("PDF CREATE"),
      actions: <Widget>[
        IconButton(
          icon: Icon(Icons.save),
          onPressed: () => savePdfFile(),
        )
      ],),
      body: pdf.addPage(Page(
      pageFormat: PdfPageFormat.a4,
      build: (BuildContext context) {
        return Center(
          child: Text("Hello Flutter"),
        );
      })),
    );

Saving pdf file to the device's location:

savePdfFile()async{
    final dir = await getExternalStorageDirectory();
    print("Directoryyyyyyyyy:${dir.path}");
    final String path = "${dir.path}/example.pdf";
    final file = File(path);
    await file.writeAsBytes(pdf.save());
     Navigator.of(context).push(
      MaterialPageRoute(builder: (_) => PgfViewerPage(path: path))
    );
  }
英文:

I'm trying to create pdf and review it.

I applied pdf plugin for creating the pdf , path_provider plugin for save the pdf to the device's storage and
flutter_full_pdf_viewer plugin for view the pdf.

I have followed create-a-pdf-in-flutter.
But getting errors in the code if I try to import with import &#39;package:pdf/widgets.dart&#39;; , material element isn't working import &#39;package:flutter/material.dart&#39;; .

如何在Flutter中创建PDF并进行审阅。

What am I doing wrong?

Code:

import &#39;dart:io&#39;;
import &#39;package:flutter/material.dart&#39;;
import &#39;package:pdf/pdf.dart&#39;;
import &#39;package:path_provider/path_provider.dart&#39;;
import &#39;package:pdfdemo/pages/pdf_viewer.dart&#39;;
//import &#39;package:pdf/widgets.dart&#39;

Variable:

final pdf = Document();

Creating pdf file page:

return Scaffold(
      appBar: AppBar(title: Text(&quot;PDF CREATE&quot;),
      actions: &lt;Widget&gt;[
        IconButton(
          icon: Icon(Icons.save),
          onPressed: () =&gt; savePdfFile(),
        )
      ],),
      body: pdf.addPage(Page(
      pageFormat: PdfPageFormat.a4,
      build: (BuildContext context) {
        return Center(
          child: Text(&quot;Hello Flutter&quot;),
        );
      })),
    );

Saving pdf file to the device's location:

savePdfFile()async{
    final dir = await getExternalStorageDirectory();
    print(&quot;Directoryyyyyyyyy:${dir.path}&quot;);
    final String path = &quot;${dir.path}/example.pdf&quot;;
    final file = File(path);
    await file.writeAsBytes(pdf.save());
     Navigator.of(context).push(
      MaterialPageRoute(builder: (_) =&gt; PgfViewerPage(path: path))
    );
  }

答案1

得分: 1

你的代码中的问题是你同时使用了Material库和PDF库。PDF插件提供的小部件在普通的Flutter Scaffold中无法正常工作。你需要像示例中展示的那样使用PDF插件构建PDF。要获取PDF文件,你需要首先生成它,然后将它传递到你想要显示它的屏幕上。

可以尝试以下方式,这对我有用:

Future<File> createPDF() {
  final Document pdf = Document();
  pdf.addPage(
    // 在此处使用插件的小部件系统设计你的PDF
    MultiPage(
      pageFormat: PdfPageFormat.letter.copyWith(marginBottom: 1.5 * PdfPageFormat.cm),
      crossAxisAlignment: CrossAxisAlignment.start,
      theme: Theme(
        tableHeader: TextStyle(fontSize: 8.0),
        tableCell: TextStyle(fontSize: 8.0),
      ),
      header: (Context context) {
        if (context.pageNumber == 1) {
          return null;
        }
        return Container(
          alignment: Alignment.centerRight,
          margin: const EdgeInsets.only(bottom: 3.0 * PdfPageFormat.mm),
          padding: const EdgeInsets.only(bottom: 3.0 * PdfPageFormat.mm),
          decoration: const BoxDecoration(
            border: BoxBorder(bottom: true, width: 0.5, color: PdfColors.grey),
          ),
          child: Text('VCR', style: Theme.of(context).defaultTextStyle.copyWith(color: PdfColors.grey)),
        );
      },
    ),
  );
  output = await getTemporaryDirectory();
  final file = File('${output.path}/example.pdf');
  file.writeAsBytesSync(pdf.save());
  return file;
}

在创建了PDF之后,可以像这样在Scaffold中显示它:

import 'package:flutter/material.dart';
import 'package:flutter_full_pdf_viewer/full_pdf_viewer_scaffold.dart';

class PDFScreen extends StatelessWidget {
  final String pathPDF;
  PDFScreen({this.pathPDF});

  @override
  Widget build(BuildContext context) {
    return PDFViewerScaffold(
      appBar: AppBar(
        title: Text("Document"),
        actions: <Widget>[
          IconButton(
            icon: Icon(Icons.share),
            onPressed: () {},
          ),
        ],
      ),
      path: pathPDF,
    );
  }
}

从第一个函数中获取pathPDF,只需调用file.absolute.path

重要提示:该函数和PDFScreen必须在不同的文件中!在实现生成PDF的函数时,绝不能导入package:flutter/material.dart

希望这对你有所帮助。

英文:

The Problem in your code is that you are using the material library and the PDF library at the same time. The Widgets that are provided by the PDF plugin dont work in the regular Scaffold from flutter. You build your PDF with them like they are showing in the example. To get the PDF file you need to generate it first and then pass it to the screen where you wanna display it.

Try it like this, it worked for me

        Future&lt;File&gt; createPDF(){
         final Document pdf = Document();
            pdf.addPage(
                //Your PDF design here with the widget system of the plugin
MultiPage(
      pageFormat:
          PdfPageFormat.letter.copyWith(marginBottom: 1.5 * PdfPageFormat.cm),
      crossAxisAlignment: CrossAxisAlignment.start,
      theme: Theme(
        tableHeader: TextStyle(fontSize: 8.0),
        tableCell: TextStyle(fontSize: 8.0),
      ),
      header: (Context context) {
        if (context.pageNumber == 1) {
          return null;
        }
        return Container(
            alignment: Alignment.centerRight,
            margin: const EdgeInsets.only(bottom: 3.0 * PdfPageFormat.mm),
            padding: const EdgeInsets.only(bottom: 3.0 * PdfPageFormat.mm),
            decoration: const BoxDecoration(
                border:
                    BoxBorder(bottom: true, width: 0.5, color: PdfColors.grey)),
            child: Text(&#39;VCR&#39;,
                style: Theme.of(context)
                    .defaultTextStyle
                    .copyWith(color: PdfColors.grey)));
      },
    );
    
    
        output = await getTemporaryDirectory();
          final file = File(&#39;${output.path}/example.pdf&#39;);
          file.writeAsBytesSync(pdf.save());
        return file;
        }

After you created the PDF display it in a scaffold like this:

import &#39;package:flutter/material.dart&#39;;
import &#39;package:flutter_full_pdf_viewer/full_pdf_viewer_scaffold.dart&#39;;


    class PDFScreen extends StatelessWidget {
      final String pathPDF;
      PDFScreen({this.pathPDF});
    
      @override
      Widget build(BuildContext context) {
        return PDFViewerScaffold(
            appBar: AppBar(
              title: Text(&quot;Document&quot;),
              actions: &lt;Widget&gt;[
                IconButton(
                  icon: Icon(Icons.share),
                  onPressed: () {},
                ),
              ],
            ),
            path: pathPDF);
      }
    }

the pathPDf you get from the first function if you call file.absolute.path

IMPORTANT: the function and the PDFScreen must be in separate files!! Where you implement the function for generating the PDF you MUST NOT import 'package:flutter/material.dart';

hope this helps

答案2

得分: 0

    import 'package:image_gallery_saver/image_gallery_saver.dart';
    import 'package:intl/intl.dart' as intl;
    import 'package:permission_handler/permission_handler.dart';
    import 'package:screenshot/screenshot.dart';
    import 'dart:typed_data';
    import 'package:syncfusion_flutter_pdf/pdf.dart';
    import 'package:path_provider/path_provider.dart';
    import 'package:open_file/open_file.dart';

    // 将小部分代码翻译,不包括注释和函数名
    // 导入必要的包
    import 'package:image_gallery_saver/image_gallery_saver.dart';
    import 'package:intl/intl.dart' as intl;
    import 'package:permission_handler/permission_handler.dart';
    import 'package:screenshot/screenshot.dart';
    import 'dart:typed_data';
    import 'package:syncfusion_flutter_pdf/pdf.dart';
    import 'package:path_provider/path_provider.dart';
    import 'package:open_file/open_file.dart';

    // 将小部分代码翻译,不包括注释和函数名
    ScreenshotController screenshotController = ScreenshotController();
    
    Screenshot(
      controller: screenshotController,
      child: Text("替换 child 为要转换成 PDF 的小部件"),
    );

    Future<void> openPDFofSS() async {
      await screenshotController.capture().then((Uint8List image) {
        setState(() {
          pdfLoading = true;
          _imageFile = image;
          _convertImageToPDF();
          saveImage(_imageFile);
        });
      }).catchError((onError) {
        print(onError);
      });
    }

    Future<void> _convertImageToPDF() async {
      PdfDocument document = PdfDocument();
      PdfPage page = document.pages.add();
      final PdfImage image = PdfBitmap(_imageFile);
      page.graphics.drawImage(
          image, Rect.fromLTWH(-20, -20, page.size.width - 50, page.size.height));
      List<int> bytes = document.save();
      document.dispose();
      Directory directory = await getApplicationDocumentsDirectory();
      String path = directory.path;
      File file = File('$path/Output.pdf');
      await file.writeAsBytes(bytes, flush: true);
      print(path);
      OpenFile.open('$path/Output.pdf');
      setState(() {
        pdfLoading = false;
      });
    }

    Future<String> saveImage(Uint8List image) async {
      await [Permission.storage].request();
      final result = await ImageGallerySaver.saveImage(image, name: 'autosmart');
      return result['filePath'];
    }
英文:
import &#39;package:image_gallery_saver/image_gallery_saver.dart&#39;;
import &#39;package:intl/intl.dart&#39; as intl;
import &#39;package:permission_handler/permission_handler.dart&#39;;
import &#39;package:screenshot/screenshot.dart&#39;;
import &#39;dart:typed_data&#39;;
import &#39;package:syncfusion_flutter_pdf/pdf.dart&#39;;
import &#39;package:path_provider/path_provider.dart&#39;;
import &#39;package:open_file/open_file.dart&#39;;
// Will take screenshot of the widget and save in Unit8List and create pdf of //Unit8List
//paste this function where needed
openPDFofSS();
//Add controller
ScreenshotController screenshotController = ScreenshotController();
//define controller before in widget as
Screenshot(
controller: screenshotController,
child: Text(&quot;replace child with the widget you want to convert in pdf&quot;),
),
// paste these function 
Future&lt;void&gt; openPDFofSS() async {
await screenshotController.capture().then((Uint8List image) {
//Capture Done
setState(() {
pdfLoading = true;
//save screenshot into Uint8List image
_imageFile = image;
//convert Unit8List image into PDF
_convertImageToPDF();
saveImage(_imageFile);
});
}).catchError((onError) {
print(onError);
});
}
Future&lt;void&gt; _convertImageToPDF() async {
//Create the PDF document
PdfDocument document = PdfDocument();
//Add the page
PdfPage page = document.pages.add();
//Load the image.
final PdfImage image = PdfBitmap(_imageFile);
//draw image to the first page
page.graphics.drawImage(
image, Rect.fromLTWH(-20, -20, page.size.width - 50, page.size.height));
//Save the docuemnt
List&lt;int&gt; bytes = document.save();
//Dispose the document.
document.dispose();
//Get external storage directory
Directory directory = await getApplicationDocumentsDirectory();
//Get directory path
String path = directory.path;
//Create an empty file to write PDF data
File file = File(&#39;$path/Output.pdf&#39;);
//Write PDF data
await file.writeAsBytes(bytes, flush: true);
print(path);
//Open the PDF document in mobile
OpenFile.open(&#39;$path/Output.pdf&#39;);
setState(() {
pdfLoading = false;
});
}
Future&lt;String&gt; saveImage(Uint8List image) async {
await [Permission.storage].request();
final result = await ImageGallerySaver.saveImage(image, name: &#39;autosmart&#39;);
return result[&#39;filePath&#39;];
}

huangapple
  • 本文由 发表于 2020年1月3日 17:19:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/59575888.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定