
离线 TA的专栏
- 打卡等级:热心大叔
- 打卡总天数:204
- 打卡月天数:0
- 打卡总奖励:3214
- 最近打卡:2023-08-27 10:45:29
|
目录
- 开发环境
- 我们如何打印
- 引入 printing 包
- 打印组合的 widgets
- widgets 内容转 image,再打印 image
- 将 widgets 内容转 image
- 整合 Image 挂件
开发环境
我们通过 - flutter create project_name
复制代码创建项目。
我们如何打印
关于调起 打印的功能。我们有以下的想法:
- 打印当前路由页面的内容,类似于网页的调用方式打印
- 打印页面中指定的的内容
- 打印重组的的内容
- 将页面指定的转化为之后,再调起打印
针对第一点,我们并没有发现在 中有类似 的方法;而对第二点,我们也不能指定页面中 进行打印。剩下的第三点和第四点,我们都可以实现。
接下来,我们将应用 包,来演示后两种实现方式。
引入 printing 包
引入 printing 很简单:
将 包添加到我们的 文件: - dependencies:
- flutter:
- sdk: flutter
- webview_flutter: ^2.0.13 # optional
- flutter_inappwebview: ^5.3.2 # optional
- # The following adds the Cupertino Icons font to your application.
- # Use with the CupertinoIcons class for iOS style icons.
- cupertino_icons: ^1.0.2
- printing: ^5.12.0
复制代码和 是可选,笔者在调试 的项目时候用到。 在编写本文时候的版本是 ,请以 官网 版本为主
然后,我们可以通过 来获取包
打印组合的 widgets
下面,我们以一个简单的案例来说说怎么使用该包,并怎么打印组合的 。
我们直接在项目的 上操作: - import 'package:pdf/pdf.dart';
- import 'package:pdf/widgets.dart' as pw;
- import 'package:printing/printing.dart';
复制代码上面引入 和 相关包。
因为我们是在 上进行调试,我们还需要在 - macos/Runner/Release.entitlements
复制代码和 - macos/Runner/DebugProfile.entitlements
复制代码文件中添加内容: - <key>com.apple.security.print</key>
- <true/>
复制代码如果是其他平台开发调试,请参考 printing 引入相关的内容。
之后我们在 中实现相关的逻辑: - @override
- Widget build(BuildContext context) {
- return Scaffold(
- appBar: AppBar(
- title: Text('Print Demo'),
- ),
- body: Center(
- child: ElevatedButton(
- onPressed: _printPdf,
- child: Text('Print'),
- ),
- ),
- );
- }
复制代码上面我们编写了相关的 ,展示一个 按钮,当点击按钮时候,触发方法 ,该方法的实现如下 - Future<void> _printPdf() async {
- try {
- final doc = pw.Document();
-
- doc.addPage(pw.Page(
- pageFormat: PdfPageFormat.a4,
- build: (pw.Context context) {
- return pw.Center(
- child: pw.Text('Hello Jimmy'),
- );
- }
- ));
-
- await Printing.layoutPdf(
- onLayout: (PdfPageFormat format) async => doc.save(),
- );
- } catch (e) {
- print(e);
- }
- }
复制代码在这个方法中,我们在 中重新组合了需要打印的 ,然后调起打印机 ,动态如下
那么,对于复杂的内容,如果我们还是编写自定义的 的话,那不切实际,维护成本高。那么,我们有什么方法打印它呢?这就是下面我们要介绍的了~
widgets 内容转 image,再打印 image
我们直接将页面上的 内容转换为 ,再结合上面提及的 打印组合的 处理即可。
将 widgets 内容转 image
先上代码: - import 'dart:typed_data';
- import 'dart:ui' as ui;
- import 'package:flutter/material.dart';
- import 'package:flutter/rendering.dart';
- import 'package:flutter/services.dart';
- class _MyHomePageState extends State<MyHomePage> {
- final GlobalKey boundaryKey = GlobalKey();
- Uint8List _imageBytes = Uint8List(0);
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- appBar: AppBar(
- title: Text('Widget to Image Demo'),
- ),
- body: Center(
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: <Widget>[
- RepaintBoundary(
- key: boundaryKey,
- child: Container(
- width: 200,
- height: 200,
- color: Colors.blue,
- child: Center(
- child: Text(
- 'Hello, Jimmy!',
- style: TextStyle(
- color: Colors.white,
- fontSize: 24,
- ),
- ),
- ),
- ),
- ),
- SizedBox(height: 20),
- ElevatedButton(
- onPressed: _capturePng,
- child: Text('Capture Image'),
- ),
- SizedBox(height: 20),
- if (!_imageBytes.isEmpty)
- Image.memory(
- _imageBytes,
- width: 200,
- height: 200,
- ),
- ],
- ),
- ),
- );
- }
- Future<void> _capturePng() async {
- try {
- RenderRepaintBoundary? boundary =
- boundaryKey.currentContext?.findRenderObject() as RenderRepaintBoundary?;
- ui.Image? image = await boundary?.toImage(pixelRatio: 3.0);
- ByteData? byteData =
- await image?.toByteData(format: ui.ImageByteFormat.png);
- setState(() {
- _imageBytes = byteData!.buffer.asUint8List(); // 赋值
- });
- } catch (e) {
- print(e);
- }
- }
- }
复制代码在代码中,我们用 来指定了重绘的区域为 的文本值。当我们点击 挂件时候,会触发 方法。在 方法中,我们将区域内的内容转换为图像,并且,将图像转为位数据,给 赋值,展现在页面上。相关 图如下
整合 Image 挂件
在上面的例子中,我们保存了生成的图数据。接下来,我们将该图片打印出来。上面的代码,我们在原始基础上更改: - ElevatedButton(
- onPressed: () => _capturePng(context),
- child: Text('Capture Image'),
- ),
复制代码引入包: - import 'package:pdf/pdf.dart';
- import 'package:pdf/widgets.dart' as pw;
- import 'package:printing/printing.dart';
复制代码然后补充 方法: - Future<void> _capturePng(BuildContext ctx) async {
- try {
- // 添加 print
- final doc = pw.Document();
- RenderRepaintBoundary? boundary = boundaryKey.currentContext
- ?.findRenderObject() as RenderRepaintBoundary?;
- ui.Image? image = await boundary?.toImage(pixelRatio: 3.0);
- ByteData? byteData =
- await image?.toByteData(format: ui.ImageByteFormat.png);
- final pageFormat = PdfPageFormat.a4;
-
- print(MediaQuery.of(ctx).size.height); // 测试打印界面的高度
- doc.addPage(pw.Page(
- pageFormat: pageFormat,
- orientation: pw.PageOrientation.landscape,
- build: (pw.Context context) {
- return pw.Center(
- child: pw.Image( // 图像挂件
- pw.MemoryImage(_imageBytes),
- width: pageFormat.height - 20,
- fit: pw.BoxFit.fitWidth,
- ),
- );
- }));
- // 打印
- await Printing.layoutPdf(
- onLayout: (PdfPageFormat format) async => doc.save(),
- );
- } catch (e) {
- print(e);
- }
- }
复制代码上面,我们通过 - pw.MemoryImage(_imageBytes)
复制代码指定 的内容,并调起打印机打印~
为了方便演示,看到边界,我们更改了下 UI
当然,我们可以设定其打印的边距和指定内容的方向等: - pw.Page(
- orientation: pw.PageOrientation.landscape, // 内容的方向
- margin: pw.EdgeInsets.all(16.0), // 边距
- ...
- )
复制代码以上就是Flutter实现打印功能的示例详解的详细内容,更多关于Flutter打印的资料请关注晓枫资讯其它相关文章!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |
晓枫资讯-科技资讯社区-免责声明
免责声明:以上内容为本网站转自其它媒体,相关信息仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同其观点或证实其内容的真实性。
1、注册用户在本社区发表、转载的任何作品仅代表其个人观点,不代表本社区认同其观点。
2、管理员及版主有权在不事先通知或不经作者准许的情况下删除其在本社区所发表的文章。
3、本社区的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,举报反馈:  进行删除处理。
4、本社区一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
5、以上声明内容的最终解释权归《晓枫资讯-科技资讯社区》所有。
|