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
2020-04-25 21:59:35 -0400
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
6b83d125877e3874664cf2f2d78d264773903848
6b83d125
1 parent
fe5ac794
Add PdfPreview Widget
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
419 additions
and
1 deletions
printing/CHANGELOG.md
printing/lib/printing.dart
printing/lib/src/pdf_preview.dart
printing/pubspec.yaml
printing/CHANGELOG.md
View file @
6b83d12
# Changelog
## 3.4.0
-
Add PdfPreview Widget
## 3.3.1
-
Remove width and height parameters from wrapWidget helper
...
...
printing/lib/printing.dart
View file @
6b83d12
...
...
@@ -16,6 +16,7 @@
export
'src/asset_utils.dart'
;
export
'src/callback.dart'
;
export
'src/pdf_preview.dart'
;
export
'src/printer.dart'
;
export
'src/printing.dart'
;
export
'src/printing_info.dart'
;
...
...
printing/lib/src/pdf_preview.dart
0 → 100644
View file @
6b83d12
import
'dart:math'
;
import
'dart:typed_data'
;
import
'package:flutter/material.dart'
;
import
'package:pdf/pdf.dart'
;
import
'package:pdf/widgets.dart'
as
pw
;
import
'callback.dart'
;
import
'printing.dart'
;
import
'printing_info.dart'
;
import
'raster.dart'
;
class
PdfPreview
extends
StatefulWidget
{
const
PdfPreview
({
Key
key
,
@required
this
.
build
,
this
.
initialPageFormat
,
this
.
allowPrinting
=
true
,
this
.
allowSharing
=
true
,
this
.
canChangePageFormat
=
true
,
this
.
actions
,
this
.
pageFormats
,
this
.
onError
,
this
.
onPrinted
,
this
.
onShared
,
})
:
super
(
key:
key
);
final
LayoutCallback
build
;
final
PdfPageFormat
initialPageFormat
;
final
bool
allowPrinting
;
final
bool
allowSharing
;
final
bool
canChangePageFormat
;
final
List
<
PdfPreviewAction
>
actions
;
final
Map
<
String
,
PdfPageFormat
>
pageFormats
;
final
Widget
Function
(
BuildContext
context
)
onError
;
final
void
Function
(
BuildContext
context
)
onPrinted
;
final
void
Function
(
BuildContext
context
)
onShared
;
@override
_PdfPreviewState
createState
()
=>
_PdfPreviewState
();
}
class
_PdfPreviewState
extends
State
<
PdfPreview
>
{
final
GlobalKey
<
State
<
StatefulWidget
>>
shareWidget
=
GlobalKey
();
final
GlobalKey
<
State
<
StatefulWidget
>>
listView
=
GlobalKey
();
final
List
<
_PdfPreviewPage
>
pages
=
<
_PdfPreviewPage
>[];
PdfPageFormat
pageFormat
;
PrintingInfo
info
=
PrintingInfo
.
unavailable
;
bool
infoLoaded
=
false
;
double
dpi
=
10
;
dynamic
error
;
static
const
Map
<
String
,
PdfPageFormat
>
defaultPageFormats
=
<
String
,
PdfPageFormat
>{
'A4'
:
PdfPageFormat
.
a4
,
'Letter'
:
PdfPageFormat
.
letter
,
};
Future
<
void
>
_raster
()
async
{
Uint8List
_doc
;
if
(!
info
.
canRaster
)
{
return
;
}
try
{
_doc
=
await
widget
.
build
(
pageFormat
);
}
catch
(
e
)
{
error
=
e
;
return
;
}
if
(
error
!=
null
)
{
setState
(()
{
error
=
null
;
});
}
int
pageNum
=
0
;
await
for
(
final
PdfRaster
page
in
Printing
.
raster
(
_doc
,
dpi:
dpi
))
{
setState
(()
{
if
(
pages
.
length
<=
pageNum
)
{
pages
.
add
(
_PdfPreviewPage
(
page:
page
));
}
else
{
pages
[
pageNum
]
=
_PdfPreviewPage
(
page:
page
);
}
});
pageNum
++;
}
pages
.
removeRange
(
pageNum
,
pages
.
length
);
}
@override
void
initState
()
{
final
Locale
locale
=
WidgetsBinding
.
instance
.
window
.
locale
??
const
Locale
(
'en'
,
'US'
);
final
String
cc
=
locale
.
countryCode
;
if
(
cc
==
'US'
||
cc
==
'CA'
||
cc
==
'MX'
)
{
pageFormat
=
widget
.
initialPageFormat
??
PdfPageFormat
.
letter
;
}
else
{
pageFormat
=
widget
.
initialPageFormat
??
PdfPageFormat
.
a4
;
}
super
.
initState
();
}
@override
void
reassemble
()
{
_raster
();
super
.
reassemble
();
}
@override
void
didUpdateWidget
(
covariant
PdfPreview
oldWidget
)
{
if
(
oldWidget
.
build
!=
widget
.
build
)
{
pages
.
clear
();
_raster
();
}
super
.
didUpdateWidget
(
oldWidget
);
}
@override
void
didChangeDependencies
()
{
if
(!
infoLoaded
)
{
Printing
.
info
().
then
((
PrintingInfo
_info
)
{
setState
(()
{
infoLoaded
=
true
;
info
=
_info
;
_raster
();
});
});
}
final
MediaQueryData
mq
=
MediaQuery
.
of
(
context
);
dpi
=
(
mq
.
size
.
width
-
16
)
*
min
(
mq
.
devicePixelRatio
,
2
)
/
pageFormat
.
width
*
72
;
_raster
();
super
.
didChangeDependencies
();
}
Widget
_showError
()
{
if
(
widget
.
onError
!=
null
)
{
return
widget
.
onError
(
context
);
}
return
const
Center
(
child:
Text
(
'Unable to display the document'
,
style:
TextStyle
(
fontSize:
20
,
),
),
);
}
Widget
_createPreview
()
{
if
(
error
!=
null
)
{
Widget
content
=
_showError
();
assert
(()
{
content
=
ErrorWidget
.
withDetails
(
message:
error
.
toString
(),
);
return
true
;
}());
return
content
;
}
if
(!
info
.
canRaster
)
{
return
_showError
();
}
if
(
pages
.
isEmpty
)
{
return
const
Center
(
child:
CircularProgressIndicator
());
}
return
Scrollbar
(
child:
ListView
.
builder
(
itemCount:
pages
.
length
,
itemBuilder:
(
BuildContext
context
,
int
index
)
=>
pages
[
index
],
),
);
}
@override
Widget
build
(
BuildContext
context
)
{
final
ThemeData
theme
=
Theme
.
of
(
context
);
final
Widget
scrollView
=
Container
(
width:
double
.
infinity
,
decoration:
BoxDecoration
(
gradient:
LinearGradient
(
colors:
<
Color
>[
Colors
.
grey
.
shade400
,
Colors
.
grey
.
shade200
],
begin:
Alignment
.
topCenter
,
end:
Alignment
.
bottomCenter
,
),
),
child:
_createPreview
(),
);
final
List
<
Widget
>
actions
=
<
Widget
>[];
if
(
widget
.
allowPrinting
&&
info
.
canPrint
)
{
actions
.
add
(
IconButton
(
icon:
const
Icon
(
Icons
.
print
),
color:
theme
.
accentIconTheme
.
color
,
onPressed:
_print
,
),
);
}
if
(
widget
.
allowSharing
&&
info
.
canShare
)
{
actions
.
add
(
IconButton
(
key:
shareWidget
,
icon:
const
Icon
(
Icons
.
share
),
color:
theme
.
accentIconTheme
.
color
,
onPressed:
_share
,
),
);
}
if
(
widget
.
canChangePageFormat
)
{
final
Map
<
String
,
PdfPageFormat
>
_pageFormats
=
widget
.
pageFormats
??
defaultPageFormats
;
final
List
<
String
>
keys
=
_pageFormats
.
keys
.
toList
();
actions
.
add
(
DropdownButton
<
PdfPageFormat
>(
style:
theme
.
accentTextTheme
.
button
,
dropdownColor:
Colors
.
grey
.
shade700
,
icon:
Icon
(
Icons
.
arrow_drop_down
,
color:
theme
.
accentIconTheme
.
color
,
),
value:
pageFormat
,
items:
List
<
DropdownMenuItem
<
PdfPageFormat
>>.
generate
(
_pageFormats
.
length
,
(
int
index
)
{
final
String
key
=
keys
[
index
];
final
PdfPageFormat
val
=
_pageFormats
[
key
];
return
DropdownMenuItem
<
PdfPageFormat
>(
child:
Text
(
key
),
value:
val
,
);
},
),
onChanged:
(
PdfPageFormat
_pageFormat
)
{
setState
(()
{
pageFormat
=
_pageFormat
;
_raster
();
});
},
),
);
}
if
(
widget
.
actions
!=
null
)
{
for
(
final
PdfPreviewAction
action
in
widget
.
actions
)
{
actions
.
add
(
IconButton
(
icon:
action
.
icon
,
color:
theme
.
accentIconTheme
.
color
,
onPressed:
action
.
onPressed
==
null
?
null
:
()
=>
action
.
onPressed
(
context
,
widget
.
build
,
pageFormat
,
),
),
);
}
}
assert
(()
{
if
(
actions
.
isNotEmpty
)
{
actions
.
add
(
Switch
(
activeColor:
Colors
.
red
,
value:
pw
.
Document
.
debug
,
onChanged:
(
bool
value
)
{
setState
(
()
{
pw
.
Document
.
debug
=
value
;
_raster
();
},
);
},
),
);
}
return
true
;
}());
return
Column
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
<
Widget
>[
Expanded
(
child:
scrollView
),
if
(
actions
.
isNotEmpty
)
Material
(
elevation:
4
,
color:
theme
.
primaryColor
,
child:
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceAround
,
children:
actions
,
),
)
],
);
}
Future
<
void
>
_print
()
async
{
final
bool
result
=
await
Printing
.
layoutPdf
(
onLayout:
widget
.
build
);
if
(
result
&&
widget
.
onPrinted
!=
null
)
{
widget
.
onPrinted
(
context
);
}
}
Future
<
void
>
_share
()
async
{
// Calculate the widget center for iPad sharing popup position
final
RenderBox
referenceBox
=
shareWidget
.
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
Uint8List
bytes
=
await
widget
.
build
(
pageFormat
);
final
bool
result
=
await
Printing
.
sharePdf
(
bytes:
bytes
,
bounds:
bounds
);
if
(
result
&&
widget
.
onShared
!=
null
)
{
widget
.
onShared
(
context
);
}
}
}
class
_PdfPreviewPage
extends
StatelessWidget
{
const
_PdfPreviewPage
({
Key
key
,
this
.
page
,
})
:
super
(
key:
key
);
final
PdfRaster
page
;
@override
Widget
build
(
BuildContext
context
)
{
final
PdfRasterImage
im
=
PdfRasterImage
(
page
);
return
Container
(
margin:
const
EdgeInsets
.
only
(
left:
8
,
top:
8
,
right:
8
,
bottom:
12
,
),
decoration:
const
BoxDecoration
(
color:
Colors
.
white
,
boxShadow:
<
BoxShadow
>[
BoxShadow
(
offset:
Offset
(
0
,
3
),
blurRadius:
5
,
color:
Color
(
0xFF000000
),
),
],
),
child:
AspectRatio
(
aspectRatio:
page
.
width
/
page
.
height
,
child:
Image
(
image:
im
,
fit:
BoxFit
.
cover
,
),
),
);
}
}
typedef
OnPdfPreviewActionPressed
=
void
Function
(
BuildContext
context
,
LayoutCallback
build
,
PdfPageFormat
pageFormat
,
);
class
PdfPreviewAction
{
const
PdfPreviewAction
({
@required
this
.
icon
,
@required
this
.
onPressed
,
})
:
assert
(
icon
!=
null
);
final
Icon
icon
;
final
OnPdfPreviewActionPressed
onPressed
;
}
...
...
printing/pubspec.yaml
View file @
6b83d12
...
...
@@ -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
:
3.
3.1
version
:
3.
4.0
environment
:
sdk
:
"
>=2.3.0
<3.0.0"
...
...
Please
register
or
login
to post a comment