Toggle navigation
Toggle navigation
This project
Loading...
Sign in
flutter_package
/
dart_pdf
Go to a project
Toggle navigation
Projects
Groups
Snippets
Help
Toggle navigation pinning
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
David PHAM-VAN
2019-09-21 07:46:15 -0400
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
593dc37de4c7439def5cae1cd5571327275fc206
593dc37d
1 parent
2bbd37bf
Add iOS Direct Print
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
235 additions
and
3 deletions
printing/CHANGELOG.md
printing/example/lib/main.dart
printing/ios/Classes/PageRenderer.swift
printing/ios/Classes/SwiftPrintingPlugin.swift
printing/lib/printing.dart
printing/lib/src/printing.dart
printing/pubspec.yaml
printing/CHANGELOG.md
View file @
593dc37
# Changelog
## 2.1.7
-
Add iOS Direct Print
## 2.1.6
-
Add qrcode to example
...
...
printing/example/lib/main.dart
View file @
593dc37
...
...
@@ -26,8 +26,11 @@ class MyApp extends StatefulWidget {
class
MyAppState
extends
State
<
MyApp
>
{
final
GlobalKey
<
State
<
StatefulWidget
>>
shareWidget
=
GlobalKey
();
final
GlobalKey
<
State
<
StatefulWidget
>>
pickWidget
=
GlobalKey
();
final
GlobalKey
<
State
<
StatefulWidget
>>
previewContainer
=
GlobalKey
();
Printer
selectedPrinter
;
Future
<
void
>
_printPdf
()
async
{
print
(
'Print ...'
);
final
bool
result
=
await
Printing
.
layoutPdf
(
...
...
@@ -50,6 +53,36 @@ class MyAppState extends State<MyApp> {
);
}
Future
<
void
>
_pickPrinter
()
async
{
print
(
'Pick printer ...'
);
// Calculate the widget center for iPad sharing popup position
final
RenderBox
referenceBox
=
pickWidget
.
currentContext
.
findRenderObject
();
final
Offset
topLeft
=
referenceBox
.
localToGlobal
(
referenceBox
.
paintBounds
.
topLeft
);
final
Offset
bottomRight
=
referenceBox
.
localToGlobal
(
referenceBox
.
paintBounds
.
bottomRight
);
final
Rect
bounds
=
Rect
.
fromPoints
(
topLeft
,
bottomRight
);
final
Printer
printer
=
await
Printing
.
pickPrinter
(
bounds:
bounds
);
setState
(()
{
selectedPrinter
=
printer
;
});
print
(
'Selected printer:
$selectedPrinter
'
);
}
Future
<
void
>
_directPrintPdf
()
async
{
print
(
'Direct print ...'
);
final
bool
result
=
await
Printing
.
directPrintPdf
(
printer:
selectedPrinter
,
onLayout:
(
PdfPageFormat
format
)
async
=>
(
await
generateDocument
(
PdfPageFormat
.
letter
)).
save
());
print
(
'Document printed:
$result
'
);
}
Future
<
void
>
_sharePdf
()
async
{
print
(
'Share ...'
);
final
pdf
.
Document
document
=
await
generateDocument
(
PdfPageFormat
.
a4
);
...
...
@@ -124,6 +157,22 @@ class MyAppState extends State<MyApp> {
children:
<
Widget
>[
RaisedButton
(
child:
const
Text
(
'Print Document'
),
onPressed:
_printPdf
),
Row
(
mainAxisSize:
MainAxisSize
.
min
,
children:
<
Widget
>[
RaisedButton
(
key:
pickWidget
,
child:
const
Text
(
'Pick Printer'
),
onPressed:
_pickPrinter
),
const
SizedBox
(
width:
10
),
RaisedButton
(
child:
Text
(
selectedPrinter
==
null
?
'Direct Print'
:
'Print to
$selectedPrinter
'
),
onPressed:
selectedPrinter
!=
null
?
_directPrintPdf
:
null
),
],
),
RaisedButton
(
key:
shareWidget
,
child:
const
Text
(
'Share Document'
),
...
...
printing/ios/Classes/PageRenderer.swift
View file @
593dc37
...
...
@@ -37,8 +37,10 @@ class PdfPrintPageRenderer: UIPrintPageRenderer {
let
page
=
pdfDocument
?
.
page
(
at
:
pageIndex
+
1
)
ctx
?
.
scaleBy
(
x
:
1.0
,
y
:
-
1.0
)
ctx
?
.
translateBy
(
x
:
0.0
,
y
:
-
paperRect
.
size
.
height
)
if
page
!=
nil
{
ctx
?
.
drawPDFPage
(
page
!
)
}
}
func
cancelJob
()
{
pdfDocument
=
nil
...
...
@@ -79,4 +81,22 @@ class PdfPrintPageRenderer: UIPrintPageRenderer {
return
pages
}
var
pageArgs
:
[
String
:
NSNumber
]
{
let
width
=
NSNumber
(
value
:
Double
(
paperRect
.
size
.
width
))
let
height
=
NSNumber
(
value
:
Double
(
paperRect
.
size
.
height
))
let
marginLeft
=
NSNumber
(
value
:
Double
(
printableRect
.
origin
.
x
))
let
marginTop
=
NSNumber
(
value
:
Double
(
printableRect
.
origin
.
y
))
let
marginRight
=
NSNumber
(
value
:
Double
(
paperRect
.
size
.
width
-
(
printableRect
.
origin
.
x
+
printableRect
.
size
.
width
)))
let
marginBottom
=
NSNumber
(
value
:
Double
(
paperRect
.
size
.
height
-
(
printableRect
.
origin
.
y
+
printableRect
.
size
.
height
)))
return
[
"width"
:
width
,
"height"
:
height
,
"marginLeft"
:
marginLeft
,
"marginTop"
:
marginTop
,
"marginRight"
:
marginRight
,
"marginBottom"
:
marginBottom
,
]
}
}
...
...
printing/ios/Classes/SwiftPrintingPlugin.swift
View file @
593dc37
...
...
@@ -35,10 +35,17 @@ public class SwiftPrintingPlugin: NSObject, FlutterPlugin, UIPrintInteractionCon
registrar
.
addMethodCallDelegate
(
instance
,
channel
:
channel
)
}
public
func
handle
(
_
call
:
FlutterMethodCall
,
result
:
FlutterResult
)
{
public
func
handle
(
_
call
:
FlutterMethodCall
,
result
:
@escaping
FlutterResult
)
{
let
args
=
call
.
arguments
!
as!
[
String
:
Any
]
if
call
.
method
==
"printPdf"
{
printPdf
(
args
[
"name"
]
as?
String
??
""
)
let
name
=
args
[
"name"
]
as?
String
??
""
printPdf
(
name
)
result
(
NSNumber
(
value
:
1
))
}
else
if
call
.
method
==
"directPrintPdf"
{
let
name
=
args
[
"name"
]
as?
String
??
""
let
printer
=
args
[
"printer"
]
as?
String
let
object
=
args
[
"doc"
]
as?
FlutterStandardTypedData
directPrintPdf
(
name
:
name
,
data
:
object
!.
data
,
withPrinter
:
printer
!
)
result
(
NSNumber
(
value
:
1
))
}
else
if
call
.
method
==
"writePdf"
{
if
let
object
=
args
[
"doc"
]
as?
FlutterStandardTypedData
{
...
...
@@ -83,6 +90,13 @@ public class SwiftPrintingPlugin: NSObject, FlutterPlugin, UIPrintInteractionCon
andBaseUrl
:
args
[
"baseUrl"
]
as?
String
==
nil
?
nil
:
URL
(
string
:
(
args
[
"baseUrl"
]
as?
String
)
!
)
)
result
(
NSNumber
(
value
:
1
))
}
else
if
call
.
method
==
"pickPrinter"
{
pickPrinter
(
result
,
withSourceRect
:
CGRect
(
x
:
CGFloat
((
args
[
"x"
]
as?
NSNumber
)?
.
floatValue
??
0.0
),
y
:
CGFloat
((
args
[
"y"
]
as?
NSNumber
)?
.
floatValue
??
0.0
),
width
:
CGFloat
((
args
[
"w"
]
as?
NSNumber
)?
.
floatValue
??
0.0
),
height
:
CGFloat
((
args
[
"h"
]
as?
NSNumber
)?
.
floatValue
??
0.0
)
))
}
else
{
result
(
FlutterMethodNotImplemented
)
}
...
...
@@ -102,6 +116,40 @@ public class SwiftPrintingPlugin: NSObject, FlutterPlugin, UIPrintInteractionCon
renderer
=
nil
}
func
directPrintPdf
(
name
:
String
,
data
:
Data
,
withPrinter
printerID
:
String
)
{
let
printing
=
UIPrintInteractionController
.
isPrintingAvailable
if
!
printing
{
let
data
:
NSDictionary
=
[
"completed"
:
false
,
"error"
:
"Printing not available"
,
]
channel
?
.
invokeMethod
(
"onCompleted"
,
arguments
:
data
)
return
}
let
controller
=
UIPrintInteractionController
.
shared
controller
.
delegate
=
self
let
printInfo
=
UIPrintInfo
.
printInfo
()
printInfo
.
jobName
=
name
printInfo
.
outputType
=
.
general
controller
.
printInfo
=
printInfo
controller
.
printingItem
=
data
let
printerURL
=
URL
(
string
:
printerID
)
if
printerURL
==
nil
{
let
data
:
NSDictionary
=
[
"completed"
:
false
,
"error"
:
"Unable to fine printer URL"
,
]
channel
?
.
invokeMethod
(
"onCompleted"
,
arguments
:
data
)
return
}
let
printer
=
UIPrinter
(
url
:
printerURL
!
)
controller
.
print
(
to
:
printer
,
completionHandler
:
completionHandler
)
}
func
printPdf
(
_
name
:
String
)
{
let
printing
=
UIPrintInteractionController
.
isPrintingAvailable
if
!
printing
{
...
...
@@ -212,4 +260,41 @@ public class SwiftPrintingPlugin: NSObject, FlutterPlugin, UIPrintInteractionCon
}
})
}
func
pickPrinter
(
_
result
:
@escaping
FlutterResult
,
withSourceRect
rect
:
CGRect
)
{
let
controller
=
UIPrinterPickerController
(
initiallySelectedPrinter
:
nil
)
let
pickPrinterCompletionHandler
:
UIPrinterPickerController
.
CompletionHandler
=
{
(
printerPickerController
:
UIPrinterPickerController
,
completed
:
Bool
,
error
:
Error
?)
in
if
!
completed
,
error
!=
nil
{
print
(
"Unable to pick printer:
\(
error
?
.
localizedDescription
??
"unknown error"
)
"
)
result
(
nil
)
return
}
if
printerPickerController
.
selectedPrinter
==
nil
{
result
(
nil
)
return
}
let
printer
=
printerPickerController
.
selectedPrinter
!
let
data
:
NSDictionary
=
[
"url"
:
printer
.
url
.
absoluteString
as
Any
,
"name"
:
printer
.
displayName
as
Any
,
"model"
:
printer
.
makeAndModel
as
Any
,
"location"
:
printer
.
displayLocation
as
Any
,
]
result
(
data
)
}
if
UI_USER_INTERFACE_IDIOM
()
==
.
pad
{
let
viewController
:
UIViewController
?
=
UIApplication
.
shared
.
keyWindow
?
.
rootViewController
if
viewController
!=
nil
{
controller
.
present
(
from
:
rect
,
in
:
viewController
!.
view
,
animated
:
true
,
completionHandler
:
pickPrinterCompletionHandler
)
return
}
}
controller
.
present
(
animated
:
true
,
completionHandler
:
pickPrinterCompletionHandler
)
}
}
...
...
printing/lib/printing.dart
View file @
593dc37
...
...
@@ -17,6 +17,7 @@
library
printing
;
import
'dart:async'
;
import
'dart:io'
;
import
'dart:typed_data'
;
import
'dart:ui'
as
ui
;
...
...
printing/lib/src/printing.dart
View file @
593dc37
...
...
@@ -18,6 +18,24 @@ part of printing;
typedef
LayoutCallback
=
FutureOr
<
List
<
int
>>
Function
(
PdfPageFormat
format
);
@immutable
class
Printer
{
const
Printer
({
@required
this
.
url
,
this
.
name
,
this
.
model
,
this
.
location
,
})
:
assert
(
url
!=
null
);
final
String
url
;
final
String
name
;
final
String
model
;
final
String
location
;
@override
String
toString
()
=>
name
??
url
;
}
mixin
Printing
{
static
const
MethodChannel
_channel
=
MethodChannel
(
'printing'
);
static
LayoutCallback
_onLayout
;
...
...
@@ -87,6 +105,61 @@ mixin Printing {
return
_onCompleted
.
future
;
}
/// Opens the native printer picker interface, and returns the URL of the selected printer.
static
Future
<
Printer
>
pickPrinter
({
Rect
bounds
})
async
{
if
(!
Platform
.
isIOS
)
{
return
null
;
}
_channel
.
setMethodCallHandler
(
_handleMethod
);
bounds
??=
Rect
.
fromCircle
(
center:
Offset
.
zero
,
radius:
10
);
final
Map
<
String
,
dynamic
>
params
=
<
String
,
dynamic
>{
'x'
:
bounds
.
left
,
'y'
:
bounds
.
top
,
'w'
:
bounds
.
width
,
'h'
:
bounds
.
height
,
};
final
Map
<
dynamic
,
dynamic
>
printer
=
await
_channel
.
invokeMethod
<
Map
<
dynamic
,
dynamic
>>(
'pickPrinter'
,
params
);
print
(
printer
);
if
(
printer
==
null
)
{
return
null
;
}
return
Printer
(
url:
printer
[
'url'
],
name:
printer
[
'name'
],
model:
printer
[
'model'
],
location:
printer
[
'location'
],
);
}
/// Prints a Pdf document to a specific local printer with no UI
///
/// returns a future with a `bool` set to true if the document is printed
/// and false if it is canceled.
/// throws an exception in case of error
static
Future
<
bool
>
directPrintPdf
({
@required
Printer
printer
,
@required
LayoutCallback
onLayout
,
String
name
=
'Document'
,
})
async
{
if
(!
Platform
.
isIOS
||
printer
==
null
)
{
return
false
;
}
_onCompleted
=
Completer
<
bool
>();
_channel
.
setMethodCallHandler
(
_handleMethod
);
final
List
<
int
>
bytes
=
await
onLayout
(
PdfPageFormat
.
standard
);
if
(
bytes
==
null
)
{
return
false
;
}
final
Map
<
String
,
dynamic
>
params
=
<
String
,
dynamic
>{
'name'
:
name
,
'printer'
:
printer
.
url
,
'doc'
:
Uint8List
.
fromList
(
bytes
),
};
await
_channel
.
invokeMethod
<
int
>(
'directPrintPdf'
,
params
);
return
_onCompleted
.
future
;
}
/// Prints a [PdfDocument] or a pdf stream to a local printer using the platform UI
@Deprecated
(
'use Printing.layoutPdf(onLayout: (_) => document.save());'
)
static
Future
<
void
>
printPdf
({
...
...
printing/pubspec.yaml
View file @
593dc37
...
...
@@ -4,7 +4,7 @@ description: Plugin that allows Flutter apps to generate and print documents to
homepage
:
https://github.com/DavBfr/dart_pdf/tree/master/printing
repository
:
https://github.com/DavBfr/dart_pdf
issue_tracker
:
https://github.com/DavBfr/dart_pdf/issues
version
:
2.1.
6
version
:
2.1.
7
environment
:
sdk
:
"
>=2.1.0
<3.0.0"
...
...
Please
register
or
login
to post a comment