Expo

Get Started
API Reference

Print

expo-print provides an API for iOS (AirPrint) and Android printing functionality.

Platform Compatibility

Android DeviceAndroid EmulatoriOS DeviceiOS SimulatorWeb

Installation

expo install expo-print

If you're installing this in a bare React Native app, you should also follow these additional installation instructions.

import * as React from 'react';
import { View, StyleSheet, Button, Platform, Text } from 'react-native';
import * as Print from 'expo-print';
import { shareAsync } from 'expo-sharing';

const html = `
<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no" />
  </head>
  <body style="text-align: center;">
    <h1 style="font-size: 50px; font-family: Helvetica Neue; font-weight: normal;">
      Hello Expo!
    </h1>
    <img
      src="https://d30j33t1r58ioz.cloudfront.net/static/guides/sdk.png"
      style="width: 90vw;" />
  </body>
</html>
`;

export default function App() {
  const [selectedPrinter, setSelectedPrinter] = React.useState();

  const print = async () => {
    // On iOS/android prints the given html. On web prints the HTML from the current page.
    await Print.printAsync({
      html,
      printerUrl: selectedPrinter?.url, // iOS only
    });
  }

  const printToFile = async () => {
    // On iOS/android prints the given html. On web prints the HTML from the current page.
    const { uri } = await Print.printToFileAsync({
      html
    });
    console.log('File has been saved to:', uri);
    await shareAsync(uri, { UTI: '.pdf', mimeType: 'application/pdf' });
  }

  const selectPrinter = async () => {
    const printer = await Print.selectPrinterAsync(); // iOS only
    setSelectedPrinter(printer);
  }

  return (
    <View style={styles.container}>
      <Button title='Print' onPress={print}  />
      <View style={styles.spacer} />
      <Button title='Print to PDF file' onPress={printToFile}/>
      {Platform.OS === 'ios' &&
        <>
          <View style={styles.spacer} />
          <Button title='Select printer' onPress={selectPrinter}/>
          <View style={styles.spacer} />
          {selectedPrinter ? <Text style={styles.printer}>{`Selected printer: ${selectedPrinter.name}`}</Text> : undefined}
        </>
      }
    </View>
  );
}

%%placeholder-start%%const styles = StyleSheet.create({ ... }); %%placeholder-end%%const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    backgroundColor: '#ecf0f1',
    flexDirection: 'column',
    padding: 8,
  },
  spacer: {
    height: 8
  },
  printer: {
    textAlign: 'center',
  }
});

import * as Print from 'expo-print';

  • options (PrintOptions) - A map defining what should be printed.

Prints a document or HTML, on web this prints the HTML from the page.

Note: On iOS, printing from HTML source doesn't support local asset URLs (due to WKWebView limitations). As a workaround you can use inlined base64-encoded strings. See this comment for more details.

  • Promise<void>

Resolves to an empty Promise if printing started.


Prints HTML to PDF file and saves it to app's cache directory. On Web this method opens the print dialog.


Available on iOS only. Chooses a printer that can be later used in printAsync

A promise which fulfils with an object containing name and url of the selected printer.

NameTypeDescription
base64
(optional)
booleanWhether to include base64 encoded string of the file in the returned object.
height
(optional)
numberHeight of the single page in pixels. Defaults to 792 which is a height of US Letter paper format with 72 PPI.
html
(optional)
stringHTML string to print into PDF file.
padding
(optional)
FilePrintPaddingPadding for the printed document.
useMarkupFormatter
(optional)
booleanAvailable on iOS only. Alternative to default option that uses UIMarkupTextPrintFormatter instead of WebView, but it doesn't display images.
width
(optional)
numberWidth of the single page in pixels. Defaults to 612 which is a width of US Letter paper format with 72 PPI.

NameTypeDescription
base64
(optional)
stringBase64 encoded string containing the data of the PDF file. Available only if base64 option is truthy. It doesn't include data URI prefix data:application/pdf;base64,.
numberOfPagesnumberNumber of pages that were needed to render given content.
uristringA URI to the printed PDF file.

NameTypeDescription
height
(optional)
numberHeight of the single page in pixels. Defaults to 792 which is a height of US Letter paper format with 72 PPI. Available only with html option.
html
(optional)
stringHTML string to print. Available on Android and iOS only.
markupFormatterIOS
(optional)
string
Available on iOS only. This argument is deprecated, use useMarkupFormatter instead. Might be removed in the future releases.
orientation
(optional)
undefined | undefinedAvailable on iOS only. The orientation of the printed content, Print.Orientation.portrait or Print.Orientation.landscape.
printerUrl
(optional)
stringURL of the printer to use. Returned from selectPrinterAsync. Available on iOS only.
uri
(optional)
stringURI of a PDF file to print. Remote, local (ex. selected via DocumentPicker) or base64 data URI starting with data:application/pdf;base64,. This only supports PDF, not other types of document (e.g. images). Available on Android and iOS only.
useMarkupFormatter
(optional)
booleanAvailable on iOS only. Alternative to default option that uses UIMarkupTextPrintFormatter instead of WebView, but it doesn't display images.
width
(optional)
numberWidth of the single page in pixels. Defaults to 612 which is a width of US Letter paper format with 72 PPI. Available only with html option.

NameTypeDescription
namestringName of the printer.
urlstringURL of the printer.

The possible values of orientation for the printed content.

NameTypeDescription
landscapestring-
portraitstring-

On iOS, printing from HTML source doesn't support local asset URLs (due to WKWebView limitations). Instead, images need to be converted to base64 and inlined into the HTML.
import { Asset } from 'expo-asset';
import { printAsync } from 'expo-print';
import { manipulateAsync } from 'expo-image-manipulator';

async function generateHTML() {
  const asset = Asset.fromModule(require('../../assets/logo.png'));
  const image = await manipulateAsync(
    asset.localUri ?? asset.uri,
    [],
    { base64: true }
  );
  return `
    <html>
      <img
        src="data:image/jpeg;base64,${image.base64}"
        style="width: 90vw;" />
    </html>
  `;
}

async function print() {
  const html = await generateHTML();
  await printAsync({ html });
}

If you're using html option in printAsync or printToFileAsync, the resulting print might contain page margins (it depends on WebView engine). They are set by @page style block and you can override them in your HTML code:
<style>
  @page {
    margin: 20px;
  }
</style>
See @page docs on MDN for more details.