Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sending a webview Page to a Printer #103

Open
ghost opened this issue Jun 20, 2018 · 13 comments
Open

Sending a webview Page to a Printer #103

ghost opened this issue Jun 20, 2018 · 13 comments

Comments

@ghost
Copy link

ghost commented Jun 20, 2018

Does anyone have a full example of sending a Webview page to a Printer ?
I am tying myself in knots with this...

@zoechi
Copy link

zoechi commented Jun 20, 2018

have you tried evalJavaScript('print();'); - just a wild guess

@ghost
Copy link
Author

ghost commented Jun 20, 2018

not yet....

@ghost
Copy link
Author

ghost commented Jun 20, 2018

I am at the point where I need to load an SPA app in.

The spa has a index.html with a few resources it loads.

In my case I store all the pages and resources in a dB with a jsonrpc Api to it running as a flutter plugin.
This allows me to store the app locally and upgrade it by synchronising the database between the clients and the server.

So if the only way of getting the index.html inside the webview am I going to have to suck the file out of my dB and eval it into the webview ? Was kind of hoping there would be a more elegant way :)

@zoechi
Copy link

zoechi commented Jun 20, 2018

You don't need eval to load a page from some local storage #23
I meant just to execute the print(); command after the page is loaded to invoke printing.

@ghost
Copy link
Author

ghost commented Jun 21, 2018

@zoechi Ah i think i get it. Let see

So i have an SPA, and pages of the SPA. If you looked at the man page its got url calls like:

<link as="script" href="/awesomeicons/_nuxt/manifest.52d743c1abd9eb763522.js" rel="preload"
<link as="script" href="/awesomeicons/_nuxt/vendor.bundle.67255c6b8df9d11c1886.js" rel="preload">
<link as="script" href="/awesomeicons/_nuxt/nuxt.bundle.3f1a09e48fb2ecac6753.js" rel="preload">
<link as="script" href="/awesomeicons/_nuxt/1.nuxt.bundle.c7475ddda41604ca49d7.js" rel="preload">
<link as="script" href="/awesomeicons/_nuxt/0.nuxt.bundle.a0eab06eb31666ee3dc7.js" rel="preload">

Basically i have to run a web server in dart and somehow get calls to _nuxt to hit the webserver ?

@zoechi
Copy link

zoechi commented Jun 21, 2018

yup, you load webview with an url that points to that web server built-in in your app

@ghost
Copy link
Author

ghost commented Jun 22, 2018

@zoechi thanks - super awesome patience in helping me.

I guess i can run the dart webserver as a true webserver with a localhost:8080.
Then just change the web code to use that localhost:8080 ?
Feels wrong since its much more IO, but thats life sometimes.

the alternative is to use file based URLs: file:///blah blah, but not sure if that will work.

@zoechi
Copy link

zoechi commented Jun 22, 2018

I don't know about the file approach either.
I guess it won't be easy with assets.
If you write it to the storage from the app it should work.
Implementing such an HTTP server that listens on localhost:xxxx is pretty easy with Dart.
It's a bit hacky but I guess there will become better ways available eventually.

@ghost
Copy link
Author

ghost commented Jun 22, 2018 via email

@zoechi
Copy link

zoechi commented Jun 22, 2018

@ghost
Copy link
Author

ghost commented Jun 23, 2018 via email

@ghost
Copy link
Author

ghost commented Jun 25, 2018

Am closing. Sorry about bring to much into this issue but I get how to solve this now.
Thank you for helping me.

@ZheruiL
Copy link

ZheruiL commented Apr 11, 2022

I've just done the same thing as you wanted to do, here's the solution:

  1. install package printing (https://pub.dev/packages/printing)
  2. add a function for the webview on page finished:
  3. get the html of the current page
  4. use printing to transform html to pdf depend on the size of the page
  5. transform pdf to png and print as image

here's the example codes:

onPageFinished: (url) {
  // detect if the page is the page you want to print
  if (url.contains('tpl/print')) {
    printPage();
  }
}
void printPage() async {
  // get the html from the current page
  String html = await _controller.runJavascriptReturningResult(
      "encodeURIComponent(document.documentElement.outerHTML)");
  html = Uri.decodeComponent(html);
  // there would be `"` at the beginning and the end, so remove it
  html = html.substring(1, html.length - 1);
  if (kDebugMode) {
    print(html);
  }

  // get the pdf of the html
  final pdf = await Printing.convertHtml(
    format: const PdfPageFormat(
      100 * PdfPageFormat.mm,
      50 * PdfPageFormat.mm,
      // marginLeft: 5 * PdfPageFormat.mm,
      // marginRight: 5 * PdfPageFormat.mm,
    ),
    html: htmlStr,
  );
  // the dpi is the resolution of the pdf, it's important if the page size is small, otherwise you can ignore it
  const dpi = 288.0;
  
  // transform pdf to image so you can print it directly
  await for (var page in Printing.raster(pdf, dpi: dpi)) {
    final imgData = await page.toPng();
    // personally I'm using sunmi printer, you'll need to change to your personnel function
    await SunmiPrinter.printImage(Uint8List.fromList(imgData));
  }
}

note: you may also install image(https://pub.dev/packages/image) for cropping or resizing images.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants