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-04-17 08:21:02 -0400
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
1c9dd3259f40d62838fdea4f0d0ad0cac5dd3a21
1c9dd325
1 parent
6391f414
Add html to pdf platform conversion
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
379 additions
and
3 deletions
.gitignore
printing/CHANGELOG.md
printing/android/src/main/java/android/print/PdfConvert.java
printing/android/src/main/java/net/nfet/flutter/printing/PrintingPlugin.java
printing/example/assets/example.html
printing/example/lib/main.dart
printing/example/pubspec.yaml
printing/ios/Classes/SwiftPrintingPlugin.swift
printing/lib/src/printing.dart
printing/pubspec.yaml
.gitignore
View file @
1c9dd32
...
...
@@ -28,6 +28,7 @@ printing/android/local.properties
printing/*.log
printing/ios/Flutter
printing/ios/Runner
printing/android/.gradle
.pana
pedantic_analyis_options_*.yaml
...
...
printing/CHANGELOG.md
View file @
1c9dd32
## 2.1.0
*
Add html to pdf platform conversion
## 2.0.4
*
Update Readme
...
...
printing/android/src/main/java/android/print/PdfConvert.java
0 → 100644
View file @
1c9dd32
/*
* Copyright (C) 2017, David PHAM-VAN <dev.nfet.net@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
android
.
print
;
import
android.app.Activity
;
import
android.os.CancellationSignal
;
import
android.os.ParcelFileDescriptor
;
import
java.io.File
;
import
java.io.FileInputStream
;
import
java.io.FileNotFoundException
;
import
java.io.IOException
;
import
java.io.InputStream
;
public
class
PdfConvert
{
public
static
void
print
(
final
Activity
activity
,
final
PrintDocumentAdapter
adapter
,
final
PrintAttributes
attributes
,
final
Result
result
)
{
adapter
.
onLayout
(
null
,
attributes
,
null
,
new
PrintDocumentAdapter
.
LayoutResultCallback
()
{
@Override
public
void
onLayoutFinished
(
PrintDocumentInfo
info
,
boolean
changed
)
{
File
outputDir
=
activity
.
getCacheDir
();
File
outputFile
=
null
;
try
{
outputFile
=
File
.
createTempFile
(
"printing"
,
"pdf"
,
outputDir
);
}
catch
(
IOException
e
)
{
outputFile
.
delete
();
result
.
onError
(
e
.
getMessage
());
return
;
}
try
{
final
File
finalOutputFile
=
outputFile
;
adapter
.
onWrite
(
new
PageRange
[]
{
PageRange
.
ALL_PAGES
},
ParcelFileDescriptor
.
open
(
outputFile
,
ParcelFileDescriptor
.
MODE_READ_WRITE
),
new
CancellationSignal
(),
new
PrintDocumentAdapter
.
WriteResultCallback
()
{
@Override
public
void
onWriteFinished
(
PageRange
[]
pages
)
{
super
.
onWriteFinished
(
pages
);
if
(
pages
.
length
==
0
)
{
finalOutputFile
.
delete
();
result
.
onError
(
"No page created"
);
}
result
.
onSuccess
(
finalOutputFile
);
finalOutputFile
.
delete
();
}
});
}
catch
(
FileNotFoundException
e
)
{
outputFile
.
delete
();
result
.
onError
(
e
.
getMessage
());
}
}
},
null
);
}
public
static
byte
[]
readFile
(
File
file
)
throws
IOException
{
byte
[]
buffer
=
new
byte
[(
int
)
file
.
length
()];
InputStream
ios
=
null
;
try
{
ios
=
new
FileInputStream
(
file
);
if
(
ios
.
read
(
buffer
)
==
-
1
)
{
throw
new
IOException
(
"EOF reached while trying to read the whole file"
);
}
}
finally
{
try
{
if
(
ios
!=
null
)
ios
.
close
();
}
catch
(
IOException
e
)
{
}
}
return
buffer
;
}
public
interface
Result
{
void
onSuccess
(
File
file
);
void
onError
(
String
message
);
}
}
...
...
printing/android/src/main/java/net/nfet/flutter/printing/PrintingPlugin.java
View file @
1c9dd32
...
...
@@ -16,22 +16,24 @@
package
net
.
nfet
.
flutter
.
printing
;
import
static
java
.
lang
.
StrictMath
.
max
;
import
android.app.Activity
;
import
android.content.Context
;
import
android.content.Intent
;
import
android.net.Uri
;
import
android.os.Build
;
import
android.os.Bundle
;
import
android.os.CancellationSignal
;
import
android.os.Environment
;
import
android.os.ParcelFileDescriptor
;
import
android.print.PageRange
;
import
android.print.PdfConvert
;
import
android.print.PrintAttributes
;
import
android.print.PrintDocumentAdapter
;
import
android.print.PrintDocumentInfo
;
import
android.print.PrintManager
;
import
android.print.pdf.PrintedPdfDocument
;
import
android.webkit.WebView
;
import
android.webkit.WebViewClient
;
import
androidx.core.content.FileProvider
;
import
java.io.File
;
...
...
@@ -155,6 +157,28 @@ public class PrintingPlugin extends PrintDocumentAdapter implements MethodCallHa
sharePdf
((
byte
[])
call
.
argument
(
"doc"
),
(
String
)
call
.
argument
(
"name"
));
result
.
success
(
0
);
break
;
case
"convertHtml"
:
double
width
=
(
double
)
call
.
argument
(
"width"
);
double
height
=
(
double
)
call
.
argument
(
"height"
);
double
marginLeft
=
(
double
)
call
.
argument
(
"marginLeft"
);
double
marginTop
=
(
double
)
call
.
argument
(
"marginTop"
);
double
marginRight
=
(
double
)
call
.
argument
(
"marginRight"
);
double
marginBottom
=
(
double
)
call
.
argument
(
"marginBottom"
);
PrintAttributes
.
Margins
margins
=
new
PrintAttributes
.
Margins
(
Double
.
valueOf
(
marginLeft
*
1000.0
).
intValue
(),
Double
.
valueOf
(
marginTop
*
1000.0
/
72.0
).
intValue
(),
Double
.
valueOf
(
marginRight
*
1000.0
/
72.0
).
intValue
(),
Double
.
valueOf
(
marginBottom
*
1000.0
/
72.0
).
intValue
());
PrintAttributes
.
MediaSize
size
=
new
PrintAttributes
.
MediaSize
(
"flutter_printing"
,
"Provided size"
,
Double
.
valueOf
(
width
*
1000.0
/
72.0
).
intValue
(),
Double
.
valueOf
(
height
*
1000.0
/
72.0
).
intValue
());
convertHtml
((
String
)
call
.
argument
(
"html"
),
size
,
margins
,
(
String
)
call
.
argument
(
"baseUrl"
));
result
.
success
(
0
);
break
;
default
:
result
.
notImplemented
();
break
;
...
...
@@ -192,4 +216,49 @@ public class PrintingPlugin extends PrintDocumentAdapter implements MethodCallHa
e
.
printStackTrace
();
}
}
private
void
convertHtml
(
String
data
,
final
PrintAttributes
.
MediaSize
size
,
final
PrintAttributes
.
Margins
margins
,
String
baseUrl
)
{
final
WebView
webView
=
new
WebView
(
activity
.
getApplicationContext
());
webView
.
loadDataWithBaseURL
(
baseUrl
,
data
,
"text/HTML"
,
"UTF-8"
,
null
);
webView
.
setWebViewClient
(
new
WebViewClient
()
{
@Override
public
void
onPageFinished
(
WebView
view
,
String
url
)
{
super
.
onPageFinished
(
view
,
url
);
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
KITKAT
)
{
PrintAttributes
attributes
=
new
PrintAttributes
.
Builder
()
.
setMediaSize
(
size
)
.
setResolution
(
new
PrintAttributes
.
Resolution
(
"pdf"
,
"pdf"
,
600
,
600
))
.
setMinMargins
(
margins
)
.
build
();
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
LOLLIPOP
)
{
final
PrintDocumentAdapter
adapter
=
webView
.
createPrintDocumentAdapter
(
"printing"
);
PdfConvert
.
print
(
activity
,
adapter
,
attributes
,
new
PdfConvert
.
Result
()
{
@Override
public
void
onSuccess
(
File
file
)
{
try
{
byte
[]
fileContent
=
PdfConvert
.
readFile
(
file
);
channel
.
invokeMethod
(
"onHtmlRendered"
,
fileContent
);
}
catch
(
IOException
e
)
{
onError
(
e
.
getMessage
());
}
}
@Override
public
void
onError
(
String
message
)
{
channel
.
invokeMethod
(
"onHtmlError"
,
message
);
}
});
}
}
}
});
}
}
...
...
printing/example/assets/example.html
0 → 100644
View file @
1c9dd32
<!DOCTYPE html>
<html>
<head>
<style>
*
{
font-family
:
Arial
,
Helvetica
,
sans-serif
;
}
table
,
th
,
td
{
border
:
1px
solid
black
;
border-collapse
:
collapse
;
}
th
,
td
{
padding
:
5px
;
}
</style>
</head>
<body>
<h2>
Html conversion
</h2>
<caption>
Sample HTML Table
</caption>
<table>
<tr>
<th>
Company
</th>
<th>
Contact
</th>
<th>
Country
</th>
</tr>
<tr>
<td>
Alfreds Futterkiste
</td>
<td>
Maria Anders
</td>
<td>
Germany
</td>
</tr>
<tr>
<td>
Centro comercial Moctezuma
</td>
<td>
Francisco Chang
</td>
<td>
Mexico
</td>
</tr>
<tr>
<td>
Ernst Handel
</td>
<td>
Roland Mendel
</td>
<td>
Austria
</td>
</tr>
<tr>
<td>
Island Trading
</td>
<td>
Helen Bennett
</td>
<td>
UK
</td>
</tr>
<tr>
<td>
Laughing Bacchus Winecellars
</td>
<td>
Yoshi Tannamuri
</td>
<td>
Canada
</td>
</tr>
<tr>
<td>
Magazzini Alimentari Riuniti
</td>
<td>
Giovanni Rovelli
</td>
<td>
Italy
</td>
</tr>
</table>
<p>
HTML links are defined with the a tag:
</p>
<a
href=
"https://github.com/DavBfr/dart_pdf"
>
This is a link
</a>
<h2>
An Unordered HTML List
</h2>
<ul>
<li>
Coffee
</li>
<li>
Tea
</li>
<li>
Milk
</li>
</ul>
<h2>
An Ordered HTML List
</h2>
<ol>
<li>
Coffee
</li>
<li>
Tea
</li>
<li>
Milk
</li>
</ol>
</body>
</html>
...
...
printing/example/lib/main.dart
View file @
1c9dd32
...
...
@@ -5,6 +5,7 @@ import 'dart:ui' as ui;
import
'package:flutter/material.dart'
;
import
'package:flutter/rendering.dart'
;
import
'package:flutter/services.dart'
;
import
'package:path_provider/path_provider.dart'
;
import
'package:pdf/pdf.dart'
;
...
...
@@ -94,6 +95,14 @@ class MyAppState extends State<MyApp> {
});
}
Future
<
void
>
_printHtml
()
async
{
print
(
'Print html ...'
);
await
Printing
.
layoutPdf
(
onLayout:
(
PdfPageFormat
format
)
async
{
final
String
html
=
await
rootBundle
.
loadString
(
'assets/example.html'
);
return
await
Printing
.
convertHtml
(
format:
format
,
html:
html
);
});
}
@override
Widget
build
(
BuildContext
context
)
{
return
RepaintBoundary
(
...
...
@@ -117,6 +126,8 @@ class MyAppState extends State<MyApp> {
onPressed:
_printScreen
),
RaisedButton
(
child:
const
Text
(
'Save to file'
),
onPressed:
_saveAsFile
),
RaisedButton
(
child:
const
Text
(
'Print Html'
),
onPressed:
_printHtml
),
],
),
),
...
...
printing/example/pubspec.yaml
View file @
1c9dd32
...
...
@@ -26,3 +26,5 @@ dependency_overrides:
flutter
:
uses-material-design
:
true
assets
:
-
assets/
...
...
printing/ios/Classes/SwiftPrintingPlugin.swift
View file @
1c9dd32
...
...
@@ -16,10 +16,12 @@
import
Flutter
import
UIKit
import
WebKit
public
class
SwiftPrintingPlugin
:
NSObject
,
FlutterPlugin
,
UIPrintInteractionControllerDelegate
{
private
var
channel
:
FlutterMethodChannel
?
private
var
renderer
:
PdfPrintPageRenderer
?
private
var
urlObservation
:
NSKeyValueObservation
?
init
(
_
channel
:
FlutterMethodChannel
?)
{
super
.
init
()
...
...
@@ -52,6 +54,30 @@ public class SwiftPrintingPlugin: NSObject, FlutterPlugin, UIPrintInteractionCon
)
}
result
(
NSNumber
(
value
:
1
))
}
else
if
call
.
method
==
"convertHtml"
{
let
width
=
CGFloat
((
args
[
"width"
]
as?
NSNumber
)?
.
floatValue
??
0.0
)
let
height
=
CGFloat
((
args
[
"height"
]
as?
NSNumber
)?
.
floatValue
??
0.0
)
let
marginLeft
=
CGFloat
((
args
[
"marginLeft"
]
as?
NSNumber
)?
.
floatValue
??
0.0
)
let
marginTop
=
CGFloat
((
args
[
"marginTop"
]
as?
NSNumber
)?
.
floatValue
??
0.0
)
let
marginRight
=
CGFloat
((
args
[
"marginRight"
]
as?
NSNumber
)?
.
floatValue
??
0.0
)
let
marginBottom
=
CGFloat
((
args
[
"marginBottom"
]
as?
NSNumber
)?
.
floatValue
??
0.0
)
convertHtml
(
(
args
[
"html"
]
as?
String
)
!
,
withPageSize
:
CGRect
(
x
:
0.0
,
y
:
0.0
,
width
:
width
,
height
:
height
),
andMargin
:
CGRect
(
x
:
marginLeft
,
y
:
marginTop
,
width
:
width
-
marginRight
-
marginLeft
,
height
:
height
-
marginBottom
-
marginTop
),
andBaseUrl
:
args
[
"baseUrl"
]
as?
String
==
nil
?
nil
:
URL
(
string
:
(
args
[
"baseUrl"
]
as?
String
)
!
)
)
result
(
NSNumber
(
value
:
1
))
}
else
{
result
(
FlutterMethodNotImplemented
)
}
...
...
@@ -118,4 +144,56 @@ public class SwiftPrintingPlugin: NSObject, FlutterPlugin, UIPrintInteractionCon
}
UIApplication
.
shared
.
keyWindow
?
.
rootViewController
?
.
present
(
activityViewController
,
animated
:
true
)
}
func
convertHtml
(
_
data
:
String
,
withPageSize
rect
:
CGRect
,
andMargin
margin
:
CGRect
,
andBaseUrl
baseUrl
:
URL
?)
{
let
viewController
=
UIApplication
.
shared
.
delegate
?
.
window
?
!.
rootViewController
let
wkWebView
=
WKWebView
(
frame
:
viewController
!.
view
.
bounds
)
wkWebView
.
isHidden
=
true
wkWebView
.
tag
=
100
viewController
?
.
view
.
addSubview
(
wkWebView
)
wkWebView
.
loadHTMLString
(
data
,
baseURL
:
baseUrl
??
Bundle
.
main
.
bundleURL
)
urlObservation
=
wkWebView
.
observe
(
\
.
isLoading
,
changeHandler
:
{
_
,
_
in
// this is workaround for issue with loading local images
DispatchQueue
.
main
.
asyncAfter
(
deadline
:
.
now
()
+
0.5
)
{
// assign the print formatter to the print page renderer
let
renderer
=
UIPrintPageRenderer
()
renderer
.
addPrintFormatter
(
wkWebView
.
viewPrintFormatter
(),
startingAtPageAt
:
0
)
// assign paperRect and printableRect values
renderer
.
setValue
(
rect
,
forKey
:
"paperRect"
)
renderer
.
setValue
(
margin
,
forKey
:
"printableRect"
)
// create pdf context and draw each page
let
pdfData
=
NSMutableData
()
UIGraphicsBeginPDFContextToData
(
pdfData
,
.
zero
,
nil
)
for
i
in
0
..<
renderer
.
numberOfPages
{
UIGraphicsBeginPDFPage
()
renderer
.
drawPage
(
at
:
i
,
in
:
UIGraphicsGetPDFContextBounds
())
}
UIGraphicsEndPDFContext
()
if
let
viewWithTag
=
viewController
?
.
view
.
viewWithTag
(
wkWebView
.
tag
)
{
viewWithTag
.
removeFromSuperview
()
// remove hidden webview when pdf is generated
// clear WKWebView cache
if
#available(iOS 9.0, *)
{
WKWebsiteDataStore
.
default
()
.
fetchDataRecords
(
ofTypes
:
WKWebsiteDataStore
.
allWebsiteDataTypes
())
{
records
in
records
.
forEach
{
record
in
WKWebsiteDataStore
.
default
()
.
removeData
(
ofTypes
:
record
.
dataTypes
,
for
:
[
record
],
completionHandler
:
{})
}
}
}
}
// dispose urlObservation
self
.
urlObservation
=
nil
let
data
=
FlutterStandardTypedData
(
bytes
:
pdfData
as
Data
)
self
.
channel
?
.
invokeMethod
(
"onHtmlRendered"
,
arguments
:
data
)
}
})
}
}
...
...
printing/lib/src/printing.dart
View file @
1c9dd32
...
...
@@ -21,6 +21,7 @@ typedef LayoutCallback = FutureOr<List<int>> Function(PdfPageFormat format);
mixin
Printing
{
static
const
MethodChannel
_channel
=
MethodChannel
(
'printing'
);
static
LayoutCallback
_onLayout
;
static
Completer
<
List
<
int
>>
_onHtmlRendered
;
static
Future
<
void
>
_handleMethod
(
MethodCall
call
)
async
{
switch
(
call
.
method
)
{
...
...
@@ -37,6 +38,12 @@ mixin Printing {
'doc'
:
Uint8List
.
fromList
(
bytes
),
};
return
await
_channel
.
invokeMethod
(
'writePdf'
,
params
);
case
'onHtmlRendered'
:
_onHtmlRendered
.
complete
(
call
.
arguments
);
break
;
case
'onHtmlError'
:
_onHtmlRendered
.
completeError
(
call
.
arguments
);
break
;
}
}
...
...
@@ -89,4 +96,25 @@ mixin Printing {
};
return
await
_channel
.
invokeMethod
(
'sharePdf'
,
params
);
}
static
Future
<
List
<
int
>>
convertHtml
(
{
@required
String
html
,
String
baseUrl
,
PdfPageFormat
format
=
PdfPageFormat
.
a4
})
async
{
final
Map
<
String
,
dynamic
>
params
=
<
String
,
dynamic
>{
'html'
:
html
,
'baseUrl'
:
baseUrl
,
'width'
:
format
.
width
,
'height'
:
format
.
height
,
'marginLeft'
:
format
.
marginLeft
,
'marginTop'
:
format
.
marginTop
,
'marginRight'
:
format
.
marginRight
,
'marginBottom'
:
format
.
marginBottom
,
};
_channel
.
setMethodCallHandler
(
_handleMethod
);
_onHtmlRendered
=
Completer
<
List
<
int
>>();
await
_channel
.
invokeMethod
<
void
>(
'convertHtml'
,
params
);
return
_onHtmlRendered
.
future
;
}
}
...
...
printing/pubspec.yaml
View file @
1c9dd32
...
...
@@ -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.
0.4
version
:
2.
1.0
environment
:
sdk
:
"
>=2.1.0
<3.0.0"
...
...
Please
register
or
login
to post a comment