With flutter printing package, how do I print a PDF from a URL? - pdf

I am using the printing package in flutter: https://pub.dev/packages/printing
The documentation shows how to create PDFs from scratch. I already have a PDF at a URL. Is there a way to retrieve it and print it with the package? Or is there an alternate method with another package?

I have tried the following ways to achieve the printing feature:
Directly get the remote data bytes
With the popular package printing
var data = await http.get(url);
await Printing.layoutPdf(onLayout: (_) => data.bodyBytes);
But I found that this way will have the printing area disorder issue when printing a roller size paper (POS printer)
Sharing (alternative of the first one)
Use the sharePdf function
var data = await http.get(url);
await Printing.sharePdf(bytes: data.bodyBytes, filename: 'my-document.pdf');
This one needs an additional step to print (click the 'functions' icon of browser then print)
View it from the browser and print it natively
Check out this package url_launcher
import 'package:url_launcher/url_launcher.dart';
if (await canLaunch(url)) {
await launch(url);
}
This one needs an additional step to print (click the 'functions' icon of browser then print)
Download the remote file and save it, use the flutter_pdf_printer package.
Use this package flutter_pdf_printer and path_provider
var data = await http.get(url);
final output = await getTemporaryDirectory();
final file = File('${output.path}/your_file_name_${new DateTime.now().microsecondsSinceEpoch}.pdf');
await file.writeAsBytes(data.bodyBytes);
await FlutterPdfPrinter.printFile(file.path);
*** this package will have channel registrant issue, please run flutter clean after installation ***
This package is a little bit outdated, but it works for me to print with a roller 80 size pdf. It uses the Swift UIKit package, which has good compatibility.
Summary
My scenario is to print a roller 80 size pdf with infinite height, the printing package doesn't work for cuz it cannot preview the pdf properly. So I changed to the last way to print, which works for me. If you just print an A4 or a regular size PDF, the printing package is still a good choice.

From the plugin documentation To save the pdf file using the path_provider library:
final output = await getTemporaryDirectory();
final file = File("${output.path}/example.pdf");
await file.writeAsBytes(pdf.save());
print the document using the iOS or Android print service
await Printing.layoutPdf(
onLayout: (PdfPageFormat format) async => pdf.save());

Convert your string url to URI, please make sure you are adding http
http: ^0.13.4
import 'package:http/http.dart' as http;
Uri uri = Uri.parse('Your link here');
http.Response response = await http.get(uri);
var pdfData = response.bodyBytes;
await Printing.layoutPdf(onLayout: (PdfPageFormat
format) async => pdfData);

Related

Not able to open PDF url using DocumentViewer ionic 4

I have a pdf URL and I want to open it using DocumentViewer. When I run code:
this._document.viewDocument(pdfUrl, 'application/pdf', options);
It is not opening PDF. I tried downloading PDF to my mobile and then open it. Please find code below:
transfer.download(downloadUrl, filename).then(entry => {
const url = entry.toURL();
if (this._plt.is('ios')) {
this._document.viewDocument(pdfUrl, 'application/pdf', options);
} else {
this._fileOpener.open(pdfUrl, 'application/pdf')
.then(() => console.log('File is opened'))
.catch(e => this.presentAlert('Error opening file', e));
}
});
I have tables and images in my PDF. When I ran above code I am not able to see HTML5 tables in the PDF.
I need help on how to open up PDF URL directly using DocumentViewer.
NOTE: I have seen a couple of post on StackOverflow suggesting to use InAppBrowser. I have a requirement where I need to display it as PDF.
I have read in https://github.com/sitewaerts/cordova-plugin-document-viewer,
that in android : Due to license restrictions in muPDF, the plugin dispatches to a separate (free) viewer app based on muPDF. If the viewer app is not yet installed, the user may be redirected to the google play app store.
https://play.google.com/store/apps/details?id=de.sitewaerts.cleverdox.viewer.
you may use other pdf plugins like
https://github.com/vadimdez/ng2-pdf-viewer/
hope this helps

React-native packager configuration - How to include .zip file in bundle?

My problem:
I have a zip file that contains a firmware update for my company's device
I want to be able to access it using react-native-fs with the code below
.
export function readAssetFile(name) {
if(Platform.OS === 'ios') {
return RNFS.readFile(`${RNFS.MainBundlePath}/assets/data/${name}`);
} else {
return RNFS.readFileAssets(`raw/${name}`, 'base64');
}
}
My project structure looks like:
ProjectDir
android
data
image1.png
image2.png
firmwarefile.zip
ios
The android branch works, because I added a build step in my .gradle to copy firmwarefile.zip into ProjectDir/android/app/src/main/assets/raw. So I can call readAssetFile('firmwarefile.zip'), and it returns the data.
On iOS, all the image files (Image1.png, Image2.png) are included in MyProject.app/assets/data/ without me having to do anything, but the zip file that sits beside them is not.
Looking into the actual packager code (from the metro project), it seems (based on metro/src/defaults.js) that zip files aren't included by default by the packager, but the packager can be configured to include other file types. But I can't find any documentation for how I'd go about doing that configuring.
Sorry for what feels like a really simple question, but I've been trying to get this zip included in my bundle for ~4 hours now. I'm resorting to manually putting in console.logs and error-throws to trace things inside metro to try and find where I should be sending in my config.
Versions:
React-native: 0.55.3
Metro: 0.30.2
This is a hack, but it gets it done:
Convert your zip binary to a base64 string
Stick it in a .js file, a la module.exports = "<your base64 data goes here>"
In your file that needs the zip file, use import myZipFileAsBase64 from './hacky-base64-file.js';
Here's a quick script to make your base64 files:
var fs = require('fs');
function prepareZip(file, outJs) {
const b64 = fs.readFileSync(file, 'base64');
fs.writeFileSync(outJs, `module.exports = ${JSON.stringify(b64)};`);
}
prepareZip('./data/myFirmware.zip', './hacky-base64-file.js');

Open URL from file system using PhantomJS

In page.open I can read about how to open a page using http.
How do use the WebPage module to open an url from the file system?
I have tried to omit http:// and have an url with ../some_dir/foo.html, but it seems to fail.
I Have tried this:
var page = require('webpage').create();
var fs = require('fs');
fs.changeWorkingDirectory('../foo/bar');
page.open('file://index.html', function(status)
{
console.log(status);
//console.log(document.title);
phantom.exit();
});
which outputs "fail".
I got the advice to test an absolute path, trying this:
var page = require('webpage').create();
var fs = require('fs');
page.open('file:///absolute/path/to/index.html', function(status)
{
console.log(page.title);
console.log($('body').length);
phantom.exit();
});
(with and without the call to changeWorkingDirectory, but with the same result)
I get a page title, but phantomjs reports that $ is undefined, jQuery is included in my html file (that is too large to post here). It is included like this:
<script type="text/javascript" src="js/jquery-1.11.1.min.js"></script>
Trying to run functions also produces errors like
CanĀ“t find variable: function_name
Does the page/file you are opening already have jquery embedded on the page? If not, you will need to use either injectJs or includeJs on the page object before you can use the $ operator.
http://phantomjs.org/page-automation.html
If you are just doing a simple DOM selection, I would recommend just calling
document.querySelector('body').length
As these functions already exist within the Phantom instance.

Navigating site (including forms) with PhantomJS

I'm trying to automate an application that uses form security in order to upload a file and then scrape data from the returned HTML.
I started out using the solution from this question. I can define my steps and get through the entire workflow as long as the last step is rendering the page.
Here are the two steps that are the meat of my script:
function() {
page.open("https://remotesite.com/do/something", function(status) {
if ('success' === status) {
page.uploadFile('input[name=file]', 'x.csv');
page.evaluate(function() {
// assignButton is used to associate modules with an account
document.getElementById("assignButton").click();
});
}
});
},
function() {
page.render('upload-results.png');
page.evaluate(function() {
var results = document.getElementById("moduleProcessingReport");
console.log("results: " + results);
});
},
When I run the script, I see that the output render is correct. However, the evaluate part isn't working. I can confirm that my DOM selection is correct by running it in the Javascript console while on the remote site.
I have seen other questions, but they revolve around using setTimeout. Unfortunately, the step strategy from the original approach already has a timeout.
UPDATE
I tried a slightly different approach, using this post and got similar results. I believe that document uses an older PhantomJS API, so I used the 'onLoadFinished' event to drive between steps.
i recomend you use casperjs or if you use PJS's webPage.injectScript() you could load up jquery and then your own script to do form input/navigation.

Windows 8 RT - Dynamically generating html does not render images

I am unable to get images loaded on a webpage when in the LocalState directory.
Specifically, there appears to be a security issue when attempting to launch the webpage when the file path is referencing the LocalState directory.
The webpage DOES load with images when I right-click the html file and view it in the browser within Visual Studio.
I have changed the path of the src tag to: src="ms-appdata:///Local/Logo.jpeg"
It doesn't work.
Help me...
Example code
public static async Task Update(WebView webview, IStorageFile file) {
var html = await Windows.Storage.PathIO.ReadTextAsync(file.Path);
webview.NavigateToString(html);
}
The NavigateToString method doesn't work with tags that point to images in the LocalData folder. (as far as I recall anyway). In fact NavigateToString also breaks JavaScript and CSS links.
Images on Server
One solution, is to change your source to point to a network server instead of localdata. I'm not sure it that works for your app scenario though.
Images and HTML as content
The second choice is to add your html and image files as content to your app and use
WebView1.Navigate(new Uri("ms-appx-web:///assets/SampleHtmlPage.html"));
to load the HTML.
In Process HTTP Server
Here is a solution that uses a custom HTTP server in the app to handle the issues.
Loading Local HTML Content in Metro WebView (Windows 8)
Base 64 encoded image
Finally, there is another solution using Base64 encoding of your images in the LocalData folder.
internal async void MakeHtmlString()
{
StorageFile imageFile; // get image file here.
var html =
string.Format("<div><img src='data:image/png;base64,{0}'",
await GetImageBase64(imageFile));
}
internal async Task<string> GetImageBase64(StorageFile imageFile)
{
var imageStream = await imageFile.OpenAsync(FileAccessMode.Read);
var inputStream = imageStream.GetInputStreamAt(0);
var dataReader = new DataReader(inputStream);
var dataResults = await dataReader.LoadAsync((uint)imageStream.Size);
var bytes = new byte[dataResults];
dataReader.ReadBytes(bytes);
return Convert.ToBase64String(bytes);
}
This last approach works for images, but not for CSS files.