diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f0aa3d..e992275 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 0.8.0 +* Update android files to use namespace + ## 0.7.0 * Android: Support V2 embedding (Thanks [nikitadol](https://github.com/nikitadol)) diff --git a/README.md b/README.md index c48fb13..d522790 100644 --- a/README.md +++ b/README.md @@ -49,8 +49,15 @@ var htmlContent = var targetPath = "/your/sample/path"; var targetFileName = "example_pdf_file" -var generatedPdfFile = await FlutterHtmlToPdf.convertFromHtmlContent( - htmlContent, targetPath, targetFileName); +final generatedPdfFile = await FlutterHtmlToPdf.convertFromHtmlContent( + htmlContent: htmlContent, + printPdfConfiguration: PrintPdfConfiguration( + targetDirectory: targetPath, + targetName: targetFileName, + printSize: PrintSize.A4, + printOrientation: PrintOrientation.Portrait, + ), +); ``` Code above simply generates **PDF** file from **HTML** content. It should work with most of common HTML markers. You don’t need to add *.pdf* extension to ***targetFileName*** because plugin only generates PDF files and extension will be added automatically. diff --git a/android/build.gradle b/android/build.gradle index 8990414..710ca8d 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -2,7 +2,7 @@ group 'com.afur.flutter_html_to_pdf' version '1.0-SNAPSHOT' buildscript { - ext.kotlin_version = '1.3.50' + ext.kotlin_version = '1.5.20' repositories { google() mavenCentral() @@ -25,6 +25,7 @@ apply plugin: 'com.android.library' apply plugin: 'kotlin-android' android { + namespace "com.afur.flutter_html_to_pdf_example" compileSdkVersion 30 compileOptions { diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml index 595dc51..a2f47b6 100644 --- a/android/src/main/AndroidManifest.xml +++ b/android/src/main/AndroidManifest.xml @@ -1,3 +1,2 @@ - + diff --git a/android/src/main/kotlin/com/afur/flutter_html_to_pdf/FlutterHtmlToPdfPlugin.kt b/android/src/main/kotlin/com/afur/flutter_html_to_pdf/FlutterHtmlToPdfPlugin.kt index fe9600f..95876f9 100644 --- a/android/src/main/kotlin/com/afur/flutter_html_to_pdf/FlutterHtmlToPdfPlugin.kt +++ b/android/src/main/kotlin/com/afur/flutter_html_to_pdf/FlutterHtmlToPdfPlugin.kt @@ -35,8 +35,10 @@ class FlutterHtmlToPdfPlugin: FlutterPlugin, MethodCallHandler { private fun convertHtmlToPdf(call: MethodCall, result: Result) { val htmlFilePath = call.argument("htmlFilePath") + val printSize = call.argument("printSize") + val orientation = call.argument("orientation") - HtmlToPdfConverter().convert(htmlFilePath!!, applicationContext, object : HtmlToPdfConverter.Callback { + HtmlToPdfConverter().convert(htmlFilePath!!, applicationContext, printSize!!, orientation!!, object : HtmlToPdfConverter.Callback { override fun onSuccess(filePath: String) { result.success(filePath) } diff --git a/android/src/main/kotlin/com/afur/flutter_html_to_pdf/HtmlToPdfConverter.kt b/android/src/main/kotlin/com/afur/flutter_html_to_pdf/HtmlToPdfConverter.kt index 8d6144e..49a7dc4 100644 --- a/android/src/main/kotlin/com/afur/flutter_html_to_pdf/HtmlToPdfConverter.kt +++ b/android/src/main/kotlin/com/afur/flutter_html_to_pdf/HtmlToPdfConverter.kt @@ -19,7 +19,7 @@ class HtmlToPdfConverter { } @SuppressLint("SetJavaScriptEnabled") - fun convert(filePath: String, applicationContext: Context, callback: Callback) { + fun convert(filePath: String, applicationContext: Context, printSize: String, orientation: String, callback: Callback) { val webView = WebView(applicationContext) val htmlContent = File(filePath).readText(Charsets.UTF_8) webView.settings.javaScriptEnabled = true @@ -29,18 +29,38 @@ class HtmlToPdfConverter { webView.webViewClient = object : WebViewClient() { override fun onPageFinished(view: WebView, url: String) { super.onPageFinished(view, url) - createPdfFromWebView(webView, applicationContext, callback) + createPdfFromWebView(webView, applicationContext, printSize, orientation, callback) } } } - fun createPdfFromWebView(webView: WebView, applicationContext: Context, callback: Callback) { + fun createPdfFromWebView(webView: WebView, applicationContext: Context, printSize: String, orientation: String, callback: Callback) { val path = applicationContext.filesDir if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + var mediaSize = PrintAttributes.MediaSize.ISO_A4 + + when (printSize) { + "A0" -> mediaSize = PrintAttributes.MediaSize.ISO_A0 + "A1" -> mediaSize = PrintAttributes.MediaSize.ISO_A1 + "A2" -> mediaSize = PrintAttributes.MediaSize.ISO_A2 + "A3" -> mediaSize = PrintAttributes.MediaSize.ISO_A3 + "A4" -> mediaSize = PrintAttributes.MediaSize.ISO_A4 + "A5" -> mediaSize = PrintAttributes.MediaSize.ISO_A5 + "A6" -> mediaSize = PrintAttributes.MediaSize.ISO_A6 + "A7" -> mediaSize = PrintAttributes.MediaSize.ISO_A7 + "A8" -> mediaSize = PrintAttributes.MediaSize.ISO_A8 + "A9" -> mediaSize = PrintAttributes.MediaSize.ISO_A9 + "A10" -> mediaSize = PrintAttributes.MediaSize.ISO_A10 + } + + when (orientation) { + "LANDSCAPE" -> mediaSize = mediaSize.asLandscape() + "PORTRAIT" -> mediaSize = mediaSize.asPortrait() + } val attributes = PrintAttributes.Builder() - .setMediaSize(PrintAttributes.MediaSize.ISO_A4) - .setResolution(PrintAttributes.Resolution("pdf", "pdf", 600, 600)) + .setMediaSize(mediaSize) + .setResolution(PrintAttributes.Resolution("pdf", "pdf", 300, 300)) .setMinMargins(PrintAttributes.Margins.NO_MARGINS).build() val printer = PdfPrinter(attributes) diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index b0ed919..dd04ba9 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -8,7 +8,7 @@ if (localPropertiesFile.exists()) { def flutterRoot = localProperties.getProperty('flutter.sdk') if (flutterRoot == null) { - throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") + throw GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") } def flutterVersionCode = localProperties.getProperty('flutter.versionCode') @@ -26,7 +26,7 @@ apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { - compileSdkVersion 30 + compileSdkVersion 33 compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 @@ -44,8 +44,8 @@ android { defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.afur.flutter_html_to_pdf_example" - minSdkVersion 16 - targetSdkVersion 30 + minSdkVersion flutter.minSdkVersion + targetSdkVersion 33 versionCode flutterVersionCode.toInteger() versionName flutterVersionName } diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index c63d539..6982e16 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -5,6 +5,7 @@ android:icon="@mipmap/ic_launcher"> CFBundleVersion 1.0 MinimumOSVersion - 8.0 + 11.0 diff --git a/example/ios/Podfile b/example/ios/Podfile index 1e8c3c9..88359b2 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -1,5 +1,5 @@ # Uncomment this line to define a global platform for your project -# platform :ios, '9.0' +# platform :ios, '11.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index c8e59bd..f76ffca 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ @@ -164,11 +164,12 @@ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0910; + LastUpgradeCheck = 1430; ORGANIZATIONNAME = "The Chromium Authors"; TargetAttributes = { 97C146ED1CF9000F007C117D = { CreatedOnToolsVersion = 7.3.1; + DevelopmentTeam = 3RQL2LD2L3; LastSwiftMigration = 0910; }; }; @@ -210,10 +211,12 @@ /* Begin PBXShellScriptBuildPhase section */ 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); inputPaths = ( + "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", ); name = "Thin Binary"; outputPaths = ( @@ -229,15 +232,15 @@ ); inputPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", - "${BUILT_PRODUCTS_DIR}/flutter_full_pdf_viewer/flutter_full_pdf_viewer.framework", "${BUILT_PRODUCTS_DIR}/flutter_html_to_pdf/flutter_html_to_pdf.framework", - "${BUILT_PRODUCTS_DIR}/path_provider/path_provider.framework", + "${BUILT_PRODUCTS_DIR}/path_provider_foundation/path_provider_foundation.framework", + "${BUILT_PRODUCTS_DIR}/pdf_viewer_plugin/pdf_viewer_plugin.framework", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_full_pdf_viewer.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_html_to_pdf.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider_foundation.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/pdf_viewer_plugin.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -246,6 +249,7 @@ }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); @@ -353,7 +357,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; @@ -374,6 +378,7 @@ "$(PROJECT_DIR)/Flutter", ); INFOPLIST_FILE = Runner/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", @@ -432,7 +437,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -479,7 +484,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; @@ -495,18 +500,20 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = 3RQL2LD2L3; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", ); INFOPLIST_FILE = Runner/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", ); - PRODUCT_BUNDLE_IDENTIFIER = com.afur.flutterHtmlToPdfExample; + PRODUCT_BUNDLE_IDENTIFIER = com.mandip.flutterHtmlToPdfExample; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -529,6 +536,7 @@ "$(PROJECT_DIR)/Flutter", ); INFOPLIST_FILE = Runner/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", diff --git a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 786d6aa..9997cfd 100644 --- a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ UIViewControllerBasedStatusBarAppearance + io.flutter.embedded_views_preview + + CADisableMinimumFrameDurationOnPhone + + UIApplicationSupportsIndirectInputEvents + diff --git a/example/lib/main.dart b/example/lib/main.dart index 0dc3237..a7c6629 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -2,14 +2,16 @@ import 'dart:async'; import 'dart:io'; import 'package:flutter/material.dart'; -import 'package:flutter_full_pdf_viewer/flutter_full_pdf_viewer.dart'; import 'package:flutter_html_to_pdf/flutter_html_to_pdf.dart'; import 'package:path_provider/path_provider.dart'; +import 'package:pdf_viewer_plugin/pdf_viewer_plugin.dart'; void main() { - runApp(MaterialApp( - home: MyApp(), - )); + runApp( + MaterialApp( + home: MyApp(), + ), + ); } class MyApp extends StatefulWidget { @@ -18,12 +20,43 @@ class MyApp extends StatefulWidget { } class _MyAppState extends State { - String generatedPdfFilePath; + String? generatedPdfFilePath; @override - void initState() { - super.initState(); - generateExampleDocument(); + Widget build(BuildContext context) { + return MaterialApp( + home: Scaffold( + body: SafeArea( + child: SizedBox( + width: MediaQuery.of(context).size.width, + child: buildBody(), + ), + ), + ), + ); + } + + Column buildBody() { + return Column( + children: [ + Expanded( + child: generatedPdfFilePath != null + ? PdfView(path: generatedPdfFilePath!) + : SizedBox(), + ), + buildButton(), + ], + ); + } + + Padding buildButton() { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 12.0), + child: ElevatedButton( + child: Text("Open Generated PDF Preview"), + onPressed: generateExampleDocument, + ), + ); } Future generateExampleDocument() async { @@ -71,26 +104,20 @@ class _MyAppState extends State { final targetPath = appDocDir.path; final targetFileName = "example-pdf"; - final generatedPdfFile = await FlutterHtmlToPdf.convertFromHtmlContent(htmlContent, targetPath, targetFileName); - generatedPdfFilePath = generatedPdfFile.path; - } - - @override - Widget build(BuildContext context) { - return MaterialApp( - home: Scaffold( - appBar: AppBar(), - body: Center( - child: ElevatedButton( - child: Text("Open Generated PDF Preview"), - onPressed: () { - Navigator.push( - context, - MaterialPageRoute(builder: (context) => PDFViewerScaffold(appBar: AppBar(title: Text("Generated PDF Document")), path: generatedPdfFilePath)), - ); - }, - ), + final generatedPdfFile = await FlutterHtmlToPdf.convertFromHtmlContent( + htmlContent: htmlContent, + printPdfConfiguration: PrintPdfConfiguration( + targetDirectory: targetPath, + targetName: targetFileName, + printSize: PrintSize.A4, + printOrientation: PrintOrientation.Portrait, ), - )); + ); + + setState( + () { + generatedPdfFilePath = generatedPdfFile.path; + }, + ); } } diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 8923a59..a91d33b 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -3,17 +3,17 @@ description: Demonstrates how to use the flutter_html_to_pdf plugin. publish_to: 'none' environment: - sdk: ">=2.0.0-dev.68.0 <3.0.0" + sdk: '>=2.18.0 <4.0.0' dependencies: flutter: sdk: flutter - path_provider: ^0.4.1 - flutter_full_pdf_viewer: ^1.0.2 + path_provider: ^2.1.0 + pdf_viewer_plugin: ^2.0.1 # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.2 + cupertino_icons: ^1.0.5 dev_dependencies: flutter_test: diff --git a/example/test/widget_test.dart b/example/test/widget_test.dart index d61f707..a5bf6b2 100644 --- a/example/test/widget_test.dart +++ b/example/test/widget_test.dart @@ -13,13 +13,13 @@ import 'package:flutter_html_to_pdf_example/main.dart'; void main() { testWidgets('Verify Platform version', (WidgetTester tester) async { // Build our app and trigger a frame. - await tester.pumpWidget(const MyApp()); + await tester.pumpWidget(MyApp()); // Verify that platform version is retrieved. expect( find.byWidgetPredicate( - (Widget widget) => widget is Text && - widget.data!.startsWith('Running on:'), + (Widget widget) => + widget is Text && widget.data!.startsWith('Running on:'), ), findsOneWidget, ); diff --git a/ios/Classes/PDFCreator.swift b/ios/Classes/PDFCreator.swift index 41b8e12..1056093 100644 --- a/ios/Classes/PDFCreator.swift +++ b/ios/Classes/PDFCreator.swift @@ -6,24 +6,26 @@ class PDFCreator { Creates a PDF using the given print formatter and saves it to the user's document directory. - returns: The generated PDF path. */ - class func create(printFormatter: UIPrintFormatter) -> URL { + class func create(printFormatter: UIPrintFormatter, width: Double, height: Double) -> URL { // assign the print formatter to the print page renderer let renderer = UIPrintPageRenderer() renderer.addPrintFormatter(printFormatter, startingAtPageAt: 0) // assign paperRect and printableRect values - let page = CGRect(x: 0, y: 0, width: 595.2, height: 841.8) // A4, 72 dpi + let page = CGRect(x: 0, y: 0, width: width, height: height) + let printable = page.insetBy(dx: 0, dy: 0) + renderer.setValue(page, forKey: "paperRect") - renderer.setValue(page, forKey: "printableRect") + renderer.setValue(printable, forKey: "printableRect") // create pdf context and draw each page let pdfData = NSMutableData() UIGraphicsBeginPDFContextToData(pdfData, .zero, nil) for i in 0..