@iftek/react-native-print 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/stale.yml +16 -0
- package/.github/workflows/windows-ci.yml +40 -0
- package/@iftek-react-native-print.podspec +19 -0
- package/LICENSE +21 -0
- package/README.md +230 -0
- package/android/.gradle/7.4/checksums/checksums.lock +0 -0
- package/android/.gradle/7.4/dependencies-accessors/dependencies-accessors.lock +0 -0
- package/android/.gradle/7.4/dependencies-accessors/gc.properties +0 -0
- package/android/.gradle/7.4/fileChanges/last-build.bin +0 -0
- package/android/.gradle/7.4/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/7.4/gc.properties +0 -0
- package/android/.gradle/vcs-1/gc.properties +0 -0
- package/android/build.gradle +24 -0
- package/android/local.properties +8 -0
- package/android/src/main/AndroidManifest.xml +4 -0
- package/android/src/main/java/com/christopherdro/RNPrint/RNPrintModule.java +237 -0
- package/android/src/main/java/com/christopherdro/RNPrint/RNPrintPackage.java +32 -0
- package/index.js +3 -0
- package/ios/RNPrint/RNPrint.h +15 -0
- package/ios/RNPrint/RNPrint.m +197 -0
- package/ios/RNPrint.xcodeproj/project.pbxproj +389 -0
- package/ios/RNPrint.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
- package/ios/RNPrint.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/ios/RNPrintTests/Info.plist +24 -0
- package/package.json +23 -0
- package/scripts/examples_postinstall.js +117 -0
- package/types/index.d.ts +19 -0
- package/windows/README.md +57 -0
- package/windows/RNPrint/PropertySheet.props +16 -0
- package/windows/RNPrint/RNPrint.cpp +375 -0
- package/windows/RNPrint/RNPrint.def +3 -0
- package/windows/RNPrint/RNPrint.h +89 -0
- package/windows/RNPrint/RNPrint.vcxproj +163 -0
- package/windows/RNPrint/RNPrint.vcxproj.filters +33 -0
- package/windows/RNPrint/ReactPackageProvider.cpp +15 -0
- package/windows/RNPrint/ReactPackageProvider.h +16 -0
- package/windows/RNPrint/ReactPackageProvider.idl +9 -0
- package/windows/RNPrint/packages.config +4 -0
- package/windows/RNPrint/pch.cpp +1 -0
- package/windows/RNPrint/pch.h +16 -0
- package/windows/RNPrint62.sln +254 -0
- package/windows/RNPrint63.sln +226 -0
@@ -0,0 +1,16 @@
|
|
1
|
+
# Number of days of inactivity before an issue becomes stale
|
2
|
+
daysUntilStale: 120
|
3
|
+
# Number of days of inactivity before a stale issue is closed
|
4
|
+
daysUntilClose: 7
|
5
|
+
# Issues with these labels will never be considered stale
|
6
|
+
exemptLabels:
|
7
|
+
- security
|
8
|
+
# Label to use when marking an issue as stale
|
9
|
+
staleLabel: stale
|
10
|
+
# Comment to post when marking an issue as stale. Set to `false` to disable
|
11
|
+
markComment: >
|
12
|
+
This issue has been automatically marked as stale because it has not had
|
13
|
+
recent activity. It will be closed if no further activity occurs. Thank you
|
14
|
+
for your contributions.
|
15
|
+
# Comment to post when closing a stale issue. Set to `false` to disable
|
16
|
+
closeComment: false
|
@@ -0,0 +1,40 @@
|
|
1
|
+
name: Windows CI
|
2
|
+
on: [pull_request]
|
3
|
+
|
4
|
+
jobs:
|
5
|
+
run-windows-tests:
|
6
|
+
name: Build & run tests
|
7
|
+
runs-on: windows-2019
|
8
|
+
|
9
|
+
steps:
|
10
|
+
- uses: actions/checkout@v2
|
11
|
+
name: Checkout Code
|
12
|
+
|
13
|
+
- name: Setup Node.js
|
14
|
+
uses: actions/setup-node@v1
|
15
|
+
with:
|
16
|
+
node-version: '12.9.1'
|
17
|
+
|
18
|
+
- name: Setup MSBuild
|
19
|
+
uses: microsoft/setup-msbuild@v1
|
20
|
+
with:
|
21
|
+
vs-version: 16.5
|
22
|
+
|
23
|
+
- name: Install node modules
|
24
|
+
run: |
|
25
|
+
cd example
|
26
|
+
yarn --pure-lockfile
|
27
|
+
- name: Build x64 release
|
28
|
+
run: |
|
29
|
+
cd example
|
30
|
+
npx react-native run-windows --release --no-packager --no-launch --logging
|
31
|
+
- name: Start Appium server
|
32
|
+
shell: powershell
|
33
|
+
run: |
|
34
|
+
cd example
|
35
|
+
Start-Process PowerShell -ArgumentList "yarn appium"
|
36
|
+
|
37
|
+
- name: Run tests
|
38
|
+
run: |
|
39
|
+
cd example
|
40
|
+
yarn test:windows
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'json'
|
2
|
+
pjson = JSON.parse(File.read('package.json'))
|
3
|
+
|
4
|
+
Pod::Spec.new do |s|
|
5
|
+
s.name = '@iftek-react-native-print'
|
6
|
+
s.version = pjson["version"]
|
7
|
+
s.homepage = "https://github.com/yuan9090/react-native-print"
|
8
|
+
s.summary = pjson["description"]
|
9
|
+
s.license = pjson["license"]
|
10
|
+
s.author = { "yuan9090" => "yuan9090@gmail.com" }
|
11
|
+
|
12
|
+
s.requires_arc = true
|
13
|
+
s.platform = :ios, '7.0'
|
14
|
+
|
15
|
+
s.source = { :git => "https://github.com/yuan9090/react-native-print", :tag => "v#{s.version}" }
|
16
|
+
s.source_files = 'ios/**/*.{h,m}'
|
17
|
+
|
18
|
+
s.dependency 'React-Core'
|
19
|
+
end
|
package/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2018 Christopher Dro
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
@@ -0,0 +1,230 @@
|
|
1
|
+
# @iftek/react-native-print
|
2
|
+
|
3
|
+
Print documents using React Native.
|
4
|
+
|
5
|
+
- Fork from [react-native-print](https://github.com/christopherdro/react-native-print)
|
6
|
+
- update Android build.gradle safeExtGet, sdk 34
|
7
|
+
- update peerDependencies
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Run `npm install @iftek/react-native-print --save`
|
12
|
+
|
13
|
+
## Add it to your project
|
14
|
+
|
15
|
+
### Automatic
|
16
|
+
|
17
|
+
Run `react-native link`
|
18
|
+
|
19
|
+
### Manual
|
20
|
+
|
21
|
+
#### iOS
|
22
|
+
1. Open your project in XCode, right click on [Libraries](http://url.brentvatne.ca/jQp8) and select [Add Files to "Your Project Name](http://url.brentvatne.ca/1gqUD).
|
23
|
+
2. Choose the file `node_modules/@iftek/react-native-print/RNPrint.xcodeproj`
|
24
|
+
3. Go to `Project Manager` tab and click on your project's name. Select the name of the target and click on `Build Phases`
|
25
|
+
4. Add `libRNPrint.a` to `Link Binary With Libraries`
|
26
|
+
[(Screenshot)](http://url.brentvatne.ca/17Xfe).
|
27
|
+
|
28
|
+
#### Android
|
29
|
+
- Edit `android/settings.gradle` to included
|
30
|
+
|
31
|
+
```java
|
32
|
+
include ':react-native-print'
|
33
|
+
project(':react-native-print').projectDir = new File(rootProject.projectDir,'../node_modules/@iftek/react-native-print/android')
|
34
|
+
```
|
35
|
+
|
36
|
+
- Edit `android/app/build.gradle` file to include
|
37
|
+
|
38
|
+
```java
|
39
|
+
dependencies {
|
40
|
+
....
|
41
|
+
compile project(':react-native-print')
|
42
|
+
|
43
|
+
}
|
44
|
+
```
|
45
|
+
|
46
|
+
- Edit `MainApplication.java` to include
|
47
|
+
|
48
|
+
```java
|
49
|
+
// import the package
|
50
|
+
import com.christopherdro.RNPrint.RNPrintPackage;
|
51
|
+
|
52
|
+
// include package
|
53
|
+
new MainReactPackage(),
|
54
|
+
new RNPrintPackage(),
|
55
|
+
```
|
56
|
+
|
57
|
+
#### Windows
|
58
|
+
|
59
|
+
1. In `windows/myapp.sln` add the `RNPrint` project to your solution:
|
60
|
+
|
61
|
+
- Open the solution in Visual Studio 2019
|
62
|
+
- Right-click Solution icon in Solution Explorer > Add > Existing Project
|
63
|
+
- Select `node_modules\react-native-print\windows\RNPrint\RNPrint.vcxproj`
|
64
|
+
|
65
|
+
2. In `windows/myapp/myapp.vcxproj` ad a reference to `RNPrint` to your main application project. From Visual Studio 2019:
|
66
|
+
|
67
|
+
- Right-click main application project > Add > Reference...
|
68
|
+
- Check `RNPrint` from Solution Projects.
|
69
|
+
|
70
|
+
3. In `pch.h` add `#include "winrt/RNPrint.h"`.
|
71
|
+
|
72
|
+
4. In `app.cpp` add `PackageProviders().Append(winrt::RNPrint::ReactPackageProvider());` before `InitializeComponent();`.
|
73
|
+
|
74
|
+
### Windows print canvas
|
75
|
+
|
76
|
+
On Windows, `react-native-print` needs an element in the visual tree to add the printable pages to.
|
77
|
+
It will look for a XAML `Canvas` named `RNPrintCanvas` and use it.
|
78
|
+
This needs to be added to the XAML tree of the screens where `react-native-print` is used.
|
79
|
+
|
80
|
+
As an example, in `windows/myapp/MainPage.xaml` from the `react-native-windows` app template this can be done by adding a XAML `Grid` with an invisible `Canvas` alongside the `ReactRootView`. Change `windows/myapp/MainPage.xaml` from:
|
81
|
+
```xaml
|
82
|
+
<Page
|
83
|
+
...
|
84
|
+
>
|
85
|
+
<react:ReactRootView
|
86
|
+
x:Name="ReactRootView"
|
87
|
+
...
|
88
|
+
/>
|
89
|
+
</Page>
|
90
|
+
```
|
91
|
+
to
|
92
|
+
```xaml
|
93
|
+
<Page
|
94
|
+
...
|
95
|
+
>
|
96
|
+
<Grid>
|
97
|
+
<Canvas x:Name="RNPrintCanvas" Opacity="0" />
|
98
|
+
<react:ReactRootView
|
99
|
+
x:Name="ReactRootView"
|
100
|
+
...
|
101
|
+
/>
|
102
|
+
</Grid>
|
103
|
+
</Page>
|
104
|
+
```
|
105
|
+
|
106
|
+
|
107
|
+
## Usage
|
108
|
+
```javascript
|
109
|
+
/**
|
110
|
+
* Sample React Native App
|
111
|
+
* https://github.com/facebook/react-native
|
112
|
+
* @flow
|
113
|
+
*/
|
114
|
+
|
115
|
+
import React, { Component } from 'react';
|
116
|
+
import {
|
117
|
+
AppRegistry,
|
118
|
+
Button,
|
119
|
+
StyleSheet,
|
120
|
+
NativeModules,
|
121
|
+
Platform,
|
122
|
+
Text,
|
123
|
+
View
|
124
|
+
} from 'react-native';
|
125
|
+
|
126
|
+
|
127
|
+
import RNHTMLtoPDF from 'react-native-html-to-pdf';
|
128
|
+
import RNPrint from '@iftek/react-native-print';
|
129
|
+
|
130
|
+
export default class RNPrintExample extends Component {
|
131
|
+
state = {
|
132
|
+
selectedPrinter: null
|
133
|
+
}
|
134
|
+
|
135
|
+
// @NOTE iOS Only
|
136
|
+
selectPrinter = async () => {
|
137
|
+
const selectedPrinter = await RNPrint.selectPrinter({ x: 100, y: 100 })
|
138
|
+
this.setState({ selectedPrinter })
|
139
|
+
}
|
140
|
+
|
141
|
+
// @NOTE iOS Only
|
142
|
+
silentPrint = async () => {
|
143
|
+
if (!this.state.selectedPrinter) {
|
144
|
+
alert('Must Select Printer First')
|
145
|
+
}
|
146
|
+
|
147
|
+
const jobName = await RNPrint.print({
|
148
|
+
printerURL: this.state.selectedPrinter.url,
|
149
|
+
html: '<h1>Silent Print</h1>'
|
150
|
+
})
|
151
|
+
|
152
|
+
}
|
153
|
+
|
154
|
+
async printHTML() {
|
155
|
+
await RNPrint.print({
|
156
|
+
html: '<h1>Heading 1</h1><h2>Heading 2</h2><h3>Heading 3</h3>'
|
157
|
+
})
|
158
|
+
}
|
159
|
+
|
160
|
+
async printPDF() {
|
161
|
+
const results = await RNHTMLtoPDF.convert({
|
162
|
+
html: '<h1>Custom converted PDF Document</h1>',
|
163
|
+
fileName: 'test',
|
164
|
+
base64: true,
|
165
|
+
})
|
166
|
+
|
167
|
+
await RNPrint.print({ filePath: results.filePath })
|
168
|
+
}
|
169
|
+
|
170
|
+
async printRemotePDF() {
|
171
|
+
await RNPrint.print({ filePath: 'https://graduateland.com/api/v2/users/jesper/cv' })
|
172
|
+
}
|
173
|
+
|
174
|
+
customOptions = () => {
|
175
|
+
return (
|
176
|
+
<View>
|
177
|
+
{this.state.selectedPrinter &&
|
178
|
+
<View>
|
179
|
+
<Text>{`Selected Printer Name: ${this.state.selectedPrinter.name}`}</Text>
|
180
|
+
<Text>{`Selected Printer URI: ${this.state.selectedPrinter.url}`}</Text>
|
181
|
+
</View>
|
182
|
+
}
|
183
|
+
<Button onPress={this.selectPrinter} title="Select Printer" />
|
184
|
+
<Button onPress={this.silentPrint} title="Silent Print" />
|
185
|
+
</View>
|
186
|
+
|
187
|
+
)
|
188
|
+
}
|
189
|
+
|
190
|
+
render() {
|
191
|
+
return (
|
192
|
+
<View style={styles.container}>
|
193
|
+
{Platform.OS === 'ios' && this.customOptions()}
|
194
|
+
<Button onPress={this.printHTML} title="Print HTML" />
|
195
|
+
<Button onPress={this.printPDF} title="Print PDF" />
|
196
|
+
<Button onPress={this.printRemotePDF} title="Print Remote PDF" />
|
197
|
+
</View>
|
198
|
+
);
|
199
|
+
}
|
200
|
+
}
|
201
|
+
|
202
|
+
const styles = StyleSheet.create({
|
203
|
+
container: {
|
204
|
+
flex: 1,
|
205
|
+
justifyContent: 'center',
|
206
|
+
alignItems: 'center',
|
207
|
+
backgroundColor: '#F5FCFF',
|
208
|
+
},
|
209
|
+
});
|
210
|
+
|
211
|
+
```
|
212
|
+
|
213
|
+
### Methods
|
214
|
+
|
215
|
+
## print(options: Object)
|
216
|
+
| Param | Type | Note |
|
217
|
+
|---|---|---|
|
218
|
+
| `html` | `string` | **iOS and Android Only:** HTML string to print
|
219
|
+
| `filePath` | `string` | Local or remote file url NOTE: iOS only supports https protocols for remote
|
220
|
+
| `printerURL` | `string` | **iOS Only:** URL returned from `selectPrinterMethod()`
|
221
|
+
| `isLandscape` | `bool` | Landscape print; default value is false
|
222
|
+
| `jobName` | `string` | **iOS and Android Only:** Name of printing job; default value is "Document"
|
223
|
+
| `baseUrl` | `string` | **Android Only:** Used to resolve relative links in the HTML. Also used for the origin header when applying same origin policy (CORS). Reference [Android WebView Docs](https://developer.android.com/reference/android/webkit/WebView#loadDataWithBaseURL(java.lang.String,%20java.lang.String,%20java.lang.String,%20java.lang.String,%20java.lang.String))
|
224
|
+
|
225
|
+
|
226
|
+
## selectPrinter(options: Object)
|
227
|
+
| Param | Type | Note |
|
228
|
+
|---|---|---|
|
229
|
+
| `x` | `string` | **iPad Only:** The x position of the popup dialog
|
230
|
+
| `y` | `string` | **iPad Only:** The y position of the popup dialog
|
Binary file
|
File without changes
|
Binary file
|
Binary file
|
File without changes
|
File without changes
|
@@ -0,0 +1,24 @@
|
|
1
|
+
apply plugin: 'com.android.library'
|
2
|
+
|
3
|
+
def safeExtGet(prop, fallback) {
|
4
|
+
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
|
5
|
+
}
|
6
|
+
|
7
|
+
android {
|
8
|
+
compileSdkVersion safeExtGet('compileSdkVersion', 34)
|
9
|
+
buildToolsVersion safeExtGet('buildToolsVersion', '31.0.0')
|
10
|
+
|
11
|
+
defaultConfig {
|
12
|
+
minSdkVersion = safeExtGet('minSdkVersion', 21)
|
13
|
+
targetSdkVersion safeExtGet('targetSdkVersion', 34)
|
14
|
+
versionCode 1
|
15
|
+
versionName "1.0"
|
16
|
+
ndk {
|
17
|
+
abiFilters "armeabi-v7a", "x86"
|
18
|
+
}
|
19
|
+
}
|
20
|
+
}
|
21
|
+
|
22
|
+
dependencies {
|
23
|
+
implementation "com.facebook.react:react-native:+" // From node_modules
|
24
|
+
}
|
@@ -0,0 +1,8 @@
|
|
1
|
+
## This file must *NOT* be checked into Version Control Systems,
|
2
|
+
# as it contains information specific to your local configuration.
|
3
|
+
#
|
4
|
+
# Location of the SDK. This is only used by Gradle.
|
5
|
+
# For customization when using a Version Control System, please read the
|
6
|
+
# header note.
|
7
|
+
#Mon Feb 17 15:14:14 CST 2025
|
8
|
+
sdk.dir=/Users/brian/Library/Android/sdk
|
@@ -0,0 +1,237 @@
|
|
1
|
+
package com.christopherdro.RNPrint;
|
2
|
+
|
3
|
+
import android.content.Context;
|
4
|
+
import android.os.Build;
|
5
|
+
import android.os.Bundle;
|
6
|
+
import android.os.CancellationSignal;
|
7
|
+
import android.os.ParcelFileDescriptor;
|
8
|
+
import android.print.PageRange;
|
9
|
+
import android.print.PrintAttributes;
|
10
|
+
import android.print.PrintDocumentAdapter;
|
11
|
+
import android.print.PrintDocumentInfo;
|
12
|
+
import android.print.PrintManager;
|
13
|
+
import android.webkit.URLUtil;
|
14
|
+
import android.webkit.WebView;
|
15
|
+
import android.webkit.WebViewClient;
|
16
|
+
|
17
|
+
import androidx.annotation.RequiresApi;
|
18
|
+
|
19
|
+
import com.facebook.react.bridge.ReactApplicationContext;
|
20
|
+
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
21
|
+
import com.facebook.react.bridge.ReactMethod;
|
22
|
+
import com.facebook.react.bridge.ReadableMap;
|
23
|
+
import com.facebook.react.bridge.Promise;
|
24
|
+
import com.facebook.react.bridge.UiThreadUtil;
|
25
|
+
import com.facebook.react.modules.network.CookieJarContainer;
|
26
|
+
import com.facebook.react.modules.network.ForwardingCookieHandler;
|
27
|
+
import com.facebook.react.modules.network.OkHttpClientProvider;
|
28
|
+
|
29
|
+
import java.io.InputStream;
|
30
|
+
import java.io.OutputStream;
|
31
|
+
import java.io.FileInputStream;
|
32
|
+
import java.io.FileNotFoundException;
|
33
|
+
import java.io.FileOutputStream;
|
34
|
+
import java.io.IOException;
|
35
|
+
|
36
|
+
import okhttp3.JavaNetCookieJar;
|
37
|
+
import okhttp3.OkHttpClient;
|
38
|
+
import okhttp3.Request;
|
39
|
+
import okhttp3.Response;
|
40
|
+
|
41
|
+
/**
|
42
|
+
* NativeModule that allows JS to open emails sending apps chooser.
|
43
|
+
*/
|
44
|
+
public class RNPrintModule extends ReactContextBaseJavaModule {
|
45
|
+
|
46
|
+
ReactApplicationContext reactContext;
|
47
|
+
final String defaultJobName = "Document";
|
48
|
+
|
49
|
+
|
50
|
+
public RNPrintModule(ReactApplicationContext reactContext) {
|
51
|
+
super(reactContext);
|
52
|
+
this.reactContext = reactContext;
|
53
|
+
}
|
54
|
+
|
55
|
+
@Override
|
56
|
+
public String getName() {
|
57
|
+
return "RNPrint";
|
58
|
+
}
|
59
|
+
|
60
|
+
WebView mWebView;
|
61
|
+
|
62
|
+
@ReactMethod
|
63
|
+
public void print(final ReadableMap options, final Promise promise) {
|
64
|
+
|
65
|
+
final String html = options.hasKey("html") ? options.getString("html") : null;
|
66
|
+
final String filePath = options.hasKey("filePath") ? options.getString("filePath") : null;
|
67
|
+
final boolean isLandscape = options.hasKey("isLandscape") ? options.getBoolean("isLandscape") : false;
|
68
|
+
final String jobName = options.hasKey("jobName") ? options.getString("jobName") : defaultJobName;
|
69
|
+
final String baseUrl = options.hasKey("baseUrl") ? options.getString("baseUrl") : null;
|
70
|
+
|
71
|
+
if ((html == null && filePath == null) || (html != null && filePath != null)) {
|
72
|
+
promise.reject(getName(), "Must provide either `html` or `filePath`. Both are either missing or passed together");
|
73
|
+
return;
|
74
|
+
}
|
75
|
+
|
76
|
+
if (html != null) {
|
77
|
+
try {
|
78
|
+
UiThreadUtil.runOnUiThread(new Runnable() {
|
79
|
+
@Override
|
80
|
+
public void run() {
|
81
|
+
// Create a WebView object specifically for printing
|
82
|
+
WebView webView = new WebView(reactContext);
|
83
|
+
webView.setWebViewClient(new WebViewClient() {
|
84
|
+
public boolean shouldOverrideUrlLoading(WebView view, String url) {
|
85
|
+
return false;
|
86
|
+
}
|
87
|
+
|
88
|
+
@Override
|
89
|
+
public void onPageFinished(WebView view, String url) {
|
90
|
+
// Get the print manager.
|
91
|
+
PrintManager printManager = (PrintManager) getCurrentActivity().getSystemService(
|
92
|
+
Context.PRINT_SERVICE);
|
93
|
+
// Create a wrapper PrintDocumentAdapter to clean up when done.
|
94
|
+
PrintDocumentAdapter adapter = new PrintDocumentAdapter() {
|
95
|
+
private final PrintDocumentAdapter mWrappedInstance =
|
96
|
+
mWebView.createPrintDocumentAdapter(jobName);
|
97
|
+
@Override
|
98
|
+
public void onStart() {
|
99
|
+
mWrappedInstance.onStart();
|
100
|
+
}
|
101
|
+
@Override
|
102
|
+
public void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes,
|
103
|
+
CancellationSignal cancellationSignal, LayoutResultCallback callback,
|
104
|
+
Bundle extras) {
|
105
|
+
mWrappedInstance.onLayout(oldAttributes, newAttributes, cancellationSignal,
|
106
|
+
callback, extras);
|
107
|
+
}
|
108
|
+
@Override
|
109
|
+
public void onWrite(PageRange[] pages, ParcelFileDescriptor destination,
|
110
|
+
CancellationSignal cancellationSignal, WriteResultCallback callback) {
|
111
|
+
mWrappedInstance.onWrite(pages, destination, cancellationSignal, callback);
|
112
|
+
}
|
113
|
+
@Override
|
114
|
+
public void onFinish() {
|
115
|
+
mWrappedInstance.onFinish();
|
116
|
+
promise.resolve(jobName);
|
117
|
+
}
|
118
|
+
};
|
119
|
+
// Pass in the ViewView's document adapter.
|
120
|
+
printManager.print(jobName, adapter, null);
|
121
|
+
mWebView = null;
|
122
|
+
}
|
123
|
+
});
|
124
|
+
|
125
|
+
webView.loadDataWithBaseURL(baseUrl, html, "text/HTML", "UTF-8", null);
|
126
|
+
|
127
|
+
// Keep a reference to WebView object until you pass the PrintDocumentAdapter
|
128
|
+
// to the PrintManager
|
129
|
+
mWebView = webView;
|
130
|
+
}
|
131
|
+
});
|
132
|
+
} catch (Exception e) {
|
133
|
+
promise.reject("print_error", e);
|
134
|
+
}
|
135
|
+
} else {
|
136
|
+
try {
|
137
|
+
|
138
|
+
PrintManager printManager = (PrintManager) getCurrentActivity().getSystemService(Context.PRINT_SERVICE);
|
139
|
+
PrintDocumentAdapter pda = new PrintDocumentAdapter() {
|
140
|
+
|
141
|
+
@Override
|
142
|
+
public void onWrite(PageRange[] pages, final ParcelFileDescriptor destination, CancellationSignal cancellationSignal, final WriteResultCallback callback){
|
143
|
+
try {
|
144
|
+
boolean isUrl = URLUtil.isValidUrl(filePath);
|
145
|
+
|
146
|
+
if (isUrl) {
|
147
|
+
new Thread(new Runnable() {
|
148
|
+
public void run() {
|
149
|
+
CookieJarContainer cookieJarContainer = null;
|
150
|
+
|
151
|
+
try {
|
152
|
+
OkHttpClient client = OkHttpClientProvider.createClient();
|
153
|
+
ForwardingCookieHandler cookieHandler = new ForwardingCookieHandler(reactContext);
|
154
|
+
cookieJarContainer = (CookieJarContainer) client.cookieJar();
|
155
|
+
cookieJarContainer.setCookieJar(new JavaNetCookieJar(cookieHandler));
|
156
|
+
|
157
|
+
Request.Builder requestBuilder = new Request.Builder().url(filePath);
|
158
|
+
Response res = client.newCall(requestBuilder.build()).execute();
|
159
|
+
|
160
|
+
loadAndClose(destination, callback, res.body().byteStream());
|
161
|
+
|
162
|
+
res.close();
|
163
|
+
} catch (Exception e) {
|
164
|
+
e.printStackTrace();
|
165
|
+
} finally {
|
166
|
+
if (cookieJarContainer != null) {
|
167
|
+
cookieJarContainer.removeCookieJar();
|
168
|
+
}
|
169
|
+
}
|
170
|
+
}
|
171
|
+
}).start();
|
172
|
+
} else {
|
173
|
+
InputStream input = new FileInputStream(filePath);
|
174
|
+
loadAndClose(destination, callback, input);
|
175
|
+
}
|
176
|
+
|
177
|
+
} catch (FileNotFoundException ee){
|
178
|
+
promise.reject(getName(), "File not found");
|
179
|
+
} catch (Exception e) {
|
180
|
+
// Catch exception
|
181
|
+
promise.reject(getName(), e);
|
182
|
+
}
|
183
|
+
}
|
184
|
+
|
185
|
+
@Override
|
186
|
+
public void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes, CancellationSignal cancellationSignal, LayoutResultCallback callback, Bundle extras){
|
187
|
+
|
188
|
+
if (cancellationSignal.isCanceled()) {
|
189
|
+
callback.onLayoutCancelled();
|
190
|
+
return;
|
191
|
+
}
|
192
|
+
|
193
|
+
PrintDocumentInfo pdi = new PrintDocumentInfo.Builder(jobName).setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT).build();
|
194
|
+
|
195
|
+
callback.onLayoutFinished(pdi, true);
|
196
|
+
}
|
197
|
+
|
198
|
+
@Override
|
199
|
+
public void onFinish() {
|
200
|
+
promise.resolve(jobName);
|
201
|
+
}
|
202
|
+
};
|
203
|
+
|
204
|
+
PrintAttributes printAttributes = new PrintAttributes.Builder()
|
205
|
+
.setMediaSize(isLandscape?PrintAttributes.MediaSize.UNKNOWN_LANDSCAPE:PrintAttributes.MediaSize.UNKNOWN_PORTRAIT)
|
206
|
+
.build();
|
207
|
+
printManager.print(jobName, pda, printAttributes);
|
208
|
+
|
209
|
+
} catch (Exception e) {
|
210
|
+
promise.reject(getName(), e);
|
211
|
+
}
|
212
|
+
}
|
213
|
+
}
|
214
|
+
|
215
|
+
|
216
|
+
private void loadAndClose(ParcelFileDescriptor destination, PrintDocumentAdapter.WriteResultCallback callback, InputStream input) throws IOException {
|
217
|
+
OutputStream output = null;
|
218
|
+
output = new FileOutputStream(destination.getFileDescriptor());
|
219
|
+
|
220
|
+
byte[] buf = new byte[1024];
|
221
|
+
int bytesRead;
|
222
|
+
|
223
|
+
while ((bytesRead = input.read(buf)) > 0) {
|
224
|
+
output.write(buf, 0, bytesRead);
|
225
|
+
}
|
226
|
+
|
227
|
+
callback.onWriteFinished(new PageRange[]{PageRange.ALL_PAGES});
|
228
|
+
|
229
|
+
try {
|
230
|
+
input.close();
|
231
|
+
output.close();
|
232
|
+
} catch (IOException e) {
|
233
|
+
e.printStackTrace();
|
234
|
+
}
|
235
|
+
}
|
236
|
+
|
237
|
+
}
|
@@ -0,0 +1,32 @@
|
|
1
|
+
package com.christopherdro.RNPrint;
|
2
|
+
|
3
|
+
import java.util.Arrays;
|
4
|
+
import java.util.ArrayList;
|
5
|
+
import java.util.Collections;
|
6
|
+
import java.util.List;
|
7
|
+
|
8
|
+
import com.facebook.react.ReactPackage;
|
9
|
+
import com.facebook.react.bridge.NativeModule;
|
10
|
+
import com.facebook.react.bridge.ReactApplicationContext;
|
11
|
+
import com.facebook.react.uimanager.ViewManager;
|
12
|
+
import com.facebook.react.bridge.JavaScriptModule;
|
13
|
+
|
14
|
+
public class RNPrintPackage implements ReactPackage {
|
15
|
+
|
16
|
+
@Override
|
17
|
+
public List<NativeModule> createNativeModules(
|
18
|
+
ReactApplicationContext reactContext) {
|
19
|
+
List<NativeModule> modules = new ArrayList<NativeModule>();
|
20
|
+
|
21
|
+
modules.add(new RNPrintModule(reactContext));
|
22
|
+
|
23
|
+
return modules;
|
24
|
+
}
|
25
|
+
|
26
|
+
@Override
|
27
|
+
public List<ViewManager> createViewManagers(
|
28
|
+
ReactApplicationContext reactContext) {
|
29
|
+
return Collections.emptyList();
|
30
|
+
}
|
31
|
+
|
32
|
+
}
|
package/index.js
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
|
2
|
+
// Created by Christopher on 9/4/15.
|
3
|
+
|
4
|
+
#import <UIKit/UIKit.h>
|
5
|
+
#import <React/RCTView.h>
|
6
|
+
#import <React/RCTBridgeModule.h>
|
7
|
+
|
8
|
+
@interface RNPrint : RCTView <RCTBridgeModule, UIPrintInteractionControllerDelegate, UIPrinterPickerControllerDelegate>
|
9
|
+
@property UIPrinter *pickedPrinter;
|
10
|
+
@property NSString *filePath;
|
11
|
+
@property NSString *htmlString;
|
12
|
+
@property NSString *jobName;
|
13
|
+
@property NSURL *printerURL;
|
14
|
+
@property (nonatomic, assign) BOOL isLandscape;
|
15
|
+
@end
|