Flutter create Chinese character PDF file and print file in printer
Unfortunately it looks like the PDF library can only use ASCII characters. Here, I have attached code to generate a PFD with the English language. It also accesses the 'share' page of the mobile device so you can save the PDF to another app or send it to the printer via methods like AirPrint. Hope this helps. I have also re-written the code. I will make a pull request to your repo soon. You may want to file a bug report to David PHAM-VAN who is the author of the [PDF][1] library.
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_share/flutter_share.dart';
import 'package:pdf/pdf.dart';
import 'package:path_provider/path_provider.dart';
void main() => runApp(new MaterialApp(home: new MyApp()));
class MyApp extends StatelessWidget {
Future<PDFDocument> _generateDocument() async{
final pdf = new PDFDocument();
final page = new PDFPage(pdf, pageFormat: PDFPageFormat(216.0, 384.0));
final top = page.pageFormat.height;
final g = page.getGraphics();
final font = new PDFFont(pdf);
g.setColor(new PDFColor(0.3, 0.3, 0.3));
String text = "We can only use ASCII characters";
g.drawString(font, 12.0, text, 1.0 * PDFPageFormat.mm, top-10*PDFPageFormat.mm);
await _localFile.then((File file){
print("Saving local file");
file.writeAsBytesSync(pdf.save());
});
return pdf;
}
void _sharePDF() {
print("Print ...");
_generateDocument().then((pdf) {
_localPath.then((String path){
FlutterShare.share(fileUrl: "$path/pdf.pdf");
});
});
}
Future<File> get _localFile async {
final path = await _localPath;
return File('$path/pdf.pdf');
}
Future<String> get _localPath async {
final directory = await getApplicationDocumentsDirectory();
return directory.path;
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: const Text('Printing example'),
),
body: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
new RaisedButton(
child: new Text('Print Document'), onPressed: _sharePDF)
],
),
),
);
}
}
Edit: I can't figure out quickly how to send a pull request so just replace your main.dart with this code. Also this is the pubspec.yaml code you want/
name: testmanual
description: A new Flutter application.
# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# Read more about versioning at semver.org.
version: 1.0.0+1
environment:
sdk: ">=2.0.0-dev.68.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^0.1.2
image_picker: ^0.4.10
path_provider: "^0.4.0"
qr_flutter: ^1.1.3
printing: ^1.0.5
pdf: ^1.0.6
flutter_share: ^0.0.4
# flutter_mailer: ^0.1.1
# video_player: ^0.6.5
# datetime_picker_formfield: ^0.1.3
# device_calendar: ^0.0.6
# connectivity: ^0.3.1
# flutter_date_picker: ^0.1.2
# image_form_field: ^0.0.2
# flutter_youtube: "^1.1.1"
# cached_network_image: ^0.4.2
# share: ^0.5.3
# audioplayers: ^0.7.8
# chewie: ^0.7.0
# font_awesome_flutter: ^8.1.0
dev_dependencies:
flutter_test:
sdk: flutter
# For information on the generic Dart part of this file, see the
# following page: https://www.dartlang.org/tools/pub/pubspec
# The following section is specific to Flutter.
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
# To add assets to your application, add an assets section, like this:
assets:
- assets/ding.wav
- assets/qpon_download.pdf
- assets/open-sans.ttf
- assets/GenYoMinTW-Heavy.ttf
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.io/assets-and-images/#resolution-aware.
# For details regarding adding assets from package dependencies, see
# https://flutter.io/assets-and-images/#from-packages
# To add custom fonts to your application, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts from package dependencies,
# see https://flutter.io/custom-fonts/#from-packages
Edit 2:
Important! When you write the PDF to a file, this writes it directly to the phone. For example, if you are on iOS, go to the Files
app and you will see a folder called <your app name>
and inside, there will be 'pdf.pdf'. You may want to do a bit of cleaning or find another sharing method.
[1]: https://pub.dartlang.org/packages/pdf
GPH
Updated on December 07, 2022Comments
-
GPH over 1 year
I am trying to develop a Flutter application which can print a document to paper. I am only able to get it to work with English characters. Can someone help to make it work with Chinese please?
Here is my
main.dart
import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; import 'dart:ui'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:pdf/pdf.dart'; import 'package:printing/printing.dart'; void main() => runApp(new MaterialApp(home: new MyApp())); class MyApp extends StatelessWidget { final shareWidget = new GlobalKey(); Future<PDFDocument> _generateDocument() async{ final pdf = new PDFDocument(deflate: zlib.encode); final page = new PDFPage(pdf, pageFormat: PDFPageFormat(216.0, 384.0)); final g = page.getGraphics(); final top = page.pageFormat.height; g.setColor(new PDFColor(0.0, 1.0, 1.0)); var font = await rootBundle.load("assets/GenYoMinTW-Heavy.ttf"); PDFTTFFont ttf = new PDFTTFFont(pdf, font); //PDFTTFFont ttf = new PDFTTFFont(pdf, (new File("assets/open-sans.ttf").readAsBytesSync() as Uint8List).buffer.asByteData()); g.setColor(new PDFColor(0.3, 0.3, 0.3)); //var encoded = utf8.encode("檯號: 1"); g.drawString(ttf, 20.0, '\u4f60\u597d', 10.0 * PDFPageFormat.MM, top - 10.0 * PDFPageFormat.MM); return pdf; } void _printPdf() { print("Print ..."); // final pdf = _generateDocument(); // Printing.printPdf(document: pdf); _generateDocument().then((pdf) { Printing.printPdf(document: pdf); }); } void _sharePdf() { print("Share ..."); //final pdf = _generateDocument(); // Calculate the widget center for iPad sharing popup position final RenderBox referenceBox = shareWidget.currentContext.findRenderObject(); final topLeft = referenceBox.localToGlobal(referenceBox.paintBounds.topLeft); final bottomRight = referenceBox.localToGlobal(referenceBox.paintBounds.bottomRight); final bounds = new Rect.fromPoints(topLeft, bottomRight); _generateDocument().then((pdf) { Printing.sharePdf(document: pdf, bounds: bounds); }); } @override Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar( title: const Text('Printing example'), ), body: new Center( child: new Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: <Widget>[ new RaisedButton( child: new Text('Print Document'), onPressed: _printPdf), new RaisedButton( key: shareWidget, child: new Text('Share Document'), onPressed: _sharePdf), ], ), ), ); } }
The Screen will not go to the print preview page when using Chinese Unicode to print.
If it helps, here is my pubspec.yaml:
name: testmanual description: A new Flutter application. # The following defines the version and build number for your application. # A version number is three numbers separated by dots, like 1.2.43 # followed by an optional build number separated by a +. # Both the version and the builder number may be overridden in flutter # build by specifying --build-name and --build-number, respectively. # Read more about versioning at semver.org. version: 1.0.0+1 environment: sdk: ">=2.0.0-dev.68.0 <3.0.0" dependencies: flutter: sdk: flutter # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^0.1.2 image_picker: ^0.4.10 flutter_mailer: ^0.1.1 video_player: ^0.6.5 datetime_picker_formfield: ^0.1.3 device_calendar: ^0.0.6 connectivity: ^0.3.1 path_provider: "^0.4.0" flutter_date_picker: ^0.1.2 image_form_field: ^0.0.2 flutter_youtube: "^1.1.1" cached_network_image: ^0.4.2 qr_flutter: ^1.1.3 share: ^0.5.3 audioplayers: ^0.7.8 chewie: ^0.7.0 printing: ^1.0.5 pdf: ^1.0.6 font_awesome_flutter: ^8.1.0 dev_dependencies: flutter_test: sdk: flutter # For information on the generic Dart part of this file, see the # following page: https://www.dartlang.org/tools/pub/pubspec # The following section is specific to Flutter. flutter: # The following line ensures that the Material Icons font is # included with your application, so that you can use the icons in # the material Icons class. uses-material-design: true # To add assets to your application, add an assets section, like this: assets: - assets/ding.wav - assets/qpon_download.pdf - assets/open-sans.ttf - assets/GenYoMinTW-Heavy.ttf # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.io/assets-and-images/#resolution-aware. # For details regarding adding assets from package dependencies, see # https://flutter.io/assets-and-images/#from-packages # To add custom fonts to your application, add a fonts section here, # in this "flutter" section. Each entry in this list should have a # "family" key with the font family name, and a "fonts" key with a # list giving the asset and other descriptors for the font. For # example: # fonts: # - family: Schyler # fonts: # - asset: fonts/Schyler-Regular.ttf # - asset: fonts/Schyler-Italic.ttf # style: italic # - family: Trajan Pro # fonts: # - asset: fonts/TrajanPro.ttf # - asset: fonts/TrajanPro_Bold.ttf # weight: 700 # # For details regarding fonts from package dependencies, # see https://flutter.io/custom-fonts/#from-packages
-
iProgram over 5 yearsI have not done stuff with PDFs and flutter before. Also I am on my phone at the moment so cannot check. My guess is the compiler doesn’t understand Chinese characters? If that’s the case, try inputting the Unicode characters directly. If you can’t find out how to do this soon, I’ll help when I’m on my computer.
-
GPH over 5 yearsThank you very much! yes, it works if i use unicode characters to print. But I have a lot of character to print, so I have to translate it to unicode and print it. I think I did it incorrectly. So it only print number instead of Chinese. I will update the code and you will see. FYI, I also put a issue in GITHUB of dart_pdf. github.com/DavBfr/dart_pdf/issues/17
-
iProgram over 5 yearsNo problem. Happy to help! I shall add an answer on here soon so you can accept it and vote up. For now, you can use: chineseconverter.com/en/convert/unicode
-
iProgram over 5 yearsAlso if the user inputs Chinese characters within the app, you should not have to convert it manually as the app would already do this. You only need to convert to unicode if it is hard coded into the app.
-
GPH over 5 yearsThank you for giving me a tool to convert Chinese character to unicode. I think I made a mistake before, it only can print unicode fo symbol , it can't print Chinese Character unicode.
-
GPH over 5 yearsERROR Message: [VERBOSE-2:shell.cc(181)] Dart Error: Unhandled exception: Invalid argument(s): String contains invalid characters. #0 _UnicodeSubsetEncoder.convert (dart:convert/ascii.dart:95:9) #1 Latin1Codec.encode (dart:convert/latin1.dart:44:46) #2 PDFStream.putText (file:///Users/chongto/development/flutter/.pub-cache/hosted/pub.dartlang.org/pdf-1.0.6/lib/src/stream.dart:79:21)
-
GPH over 5 yearsSorry for bring you any inconvenience!
-
iProgram over 5 yearsI’ll see what I can do later today. Have you seen what happens when you use the Unicode string?
-
GPH over 5 yearsI will update the code now, then you can see it.
-
iProgram over 5 yearsWhat is on line 45 of
main.dart
? -
GPH over 5 yearsline 45 is _generateDocument().then((pdf) { Printing.printPdf(document: pdf); });
-
GPH over 5 yearsIn fact, i don't have to use pdf to print. But i only find out this method to print to printer. If there are other methods to print the Chinese character that are easy to do, please kindly adv. me. Thanks
-
iProgram over 5 yearsLet us continue this discussion in chat.
-
iProgram over 5 yearsI have been able to get the share functionality to work with the PDF, however I don't think we can solve the issue. I think it is a issue in the PDF library.
-
GPH over 5 yearsOK, Thank you very much for your effort! Do you know any other way to print a file to a printer? May i use txt file to print?
-
-
GPH over 5 yearsMay I use txt/csv file to print? will it be ok?
-
iProgram over 5 years@GPH You might be able to. Depends on how you want it to be laid out. Worth a try.
-
GPH over 5 yearsOK, thank you so much! I only want to print Chinese characters.
-
iProgram over 5 years@GPH Unfortunately this library doesn't seem to have support for it. Unless you or someone else can find a library that supports them; or if this library is updated, this seems the only answer for now.
-
GPH over 5 yearsThanks again and again! I will share the answer here when I found it.
-
Max Vollmer about 5 yearsIf that is your library (as your username and the name of the author of the library suggest), you must disclose it, as otherwise this is considered spam. See How to not be a spammer