Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

Capture the Appium image as PNG bytes, pass those bytes to Apache POI’s XWPFRun.addPicture, and write the resulting XWPFDocument as a .docx file. Using OutputType.BYTES avoids a temporary screenshot file and is the simplest path when the image only needs to be embedded in Word.

What you need

  • A running Appium session and the official Appium Java client. The Appium Java client is built on Selenium, so Selenium’s TakesScreenshot API supplies the capture operation.
  • Apache POI’s poi-ooxml dependency for creating modern Word .docx files.
  • A Java test or utility process that can access the active Appium driver.

Use versions that are compatible with your Java runtime, Appium server, driver, and Selenium dependency. The APIs below are the relevant interfaces; dependency versions should come from the release lines supported by your project.

Complete Java example: capture bytes and create a DOCX

This example assumes driver is an already-connected Appium driver and that the desired screen is visible. It captures a PNG in memory, inserts it into a paragraph, and saves appium-screenshot.docx.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
import io.appium.java_client.AppiumDriver;
import java.io.ByteArrayInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.Document;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;

public final class AppiumWordScreenshot {
    public static void save(AppiumDriver driver, String outputPath)
            throws IOException {
        byte[] png = ((TakesScreenshot) driver)
                .getScreenshotAs(OutputType.BYTES);

        // These dimensions are examples. Change them to fit your page.
        int widthEmu = Units.inchesToEMU(6.0);
        int heightEmu = Units.inchesToEMU(10.0);

        try (XWPFDocument document = new XWPFDocument();
             ByteArrayInputStream image = new ByteArrayInputStream(png);
             FileOutputStream output = new FileOutputStream(outputPath)) {

            XWPFParagraph paragraph = document.createParagraph();
            XWPFRun run = paragraph.createRun();
            run.addPicture(image, Document.PICTURE_TYPE_PNG,
                    "appium-screenshot.png", widthEmu, heightEmu);
            document.write(output);
        }
    }
}

Call it after navigation and any waits required by your test:

AppiumWordScreenshot.save(driver, "artifacts/appium-screenshot.docx");

addPicture expects an input stream, a picture type, a filename, and dimensions in English Metric Units (EMUs). Document.PICTURE_TYPE_PNG matches the PNG returned by the Appium/Selenium screenshot call.

Preserve the screenshot’s aspect ratio

The sample uses six inches wide and ten inches high only to show the API. A phone screenshot may be taller or wider, and forcing arbitrary dimensions can stretch it. Obtain the image’s pixel width and height with an image reader, choose the maximum width that fits your page, and calculate the other dimension:

double targetWidth = Units.toEMU(6.0);
double ratio = (double) imagePixelHeight / imagePixelWidth;
int widthEmu = (int) targetWidth;
int heightEmu = (int) (targetWidth * ratio);

In production, decode the PNG with ImageIO.read, check for a null image, and calculate from the decoded dimensions before calling addPicture.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Where to place the capture in an Appium test

  1. Start the Appium server and create the driver with the desired capabilities.
  2. Switch to the required context. Appium can capture a native context or a web context, but the visible viewport and driver support determine what is returned.
  3. Wait for the screen or element state your evidence requires. A screenshot taken before an asynchronous transition finishes can be valid technically but wrong for the test report.
  4. Call getScreenshotAs(OutputType.BYTES).
  5. Insert the bytes into the Word run and close the document after writing.

If you need one document containing several screenshots, create one XWPFDocument, create a new paragraph and run for each image, and call document.write once at the end. Reusing the document avoids producing a separate file for every step.

Choosing Selenium’s screenshot output type

Output type Best use Important detail
BYTES Direct insertion into POI Keeps the PNG in memory; wrap it in ByteArrayInputStream.
FILE A file-oriented pipeline The returned file is temporary. Copy it promptly if it must remain after the JVM exits.
BASE64 Text transports or APIs Decode the Base64 value back to image bytes before passing it to POI.

Using OutputType.FILE

File temporary = ((TakesScreenshot) driver)
        .getScreenshotAs(OutputType.FILE);
Path permanent = Path.of("artifacts", "appium-screenshot.png");
Files.copy(temporary.toPath(), permanent,
        StandardCopyOption.REPLACE_EXISTING);

Do not treat Selenium’s temporary file as a durable artifact. If your final deliverable is the Word document, BYTES generally removes this extra copy step.

Adding useful report text

A paragraph can contain a label before the image, and additional paragraphs can record the test name, timestamp, platform, or screen under test. Keep metadata separate from the image insertion so a failed capture does not produce a misleading report.

XWPFParagraph heading = document.createParagraph();
heading.createRun().setText("Checkout screen");
XWPFParagraph imageParagraph = document.createParagraph();
XWPFRun imageRun = imageParagraph.createRun();
imageRun.addPicture(image, Document.PICTURE_TYPE_PNG,
        "checkout.png", widthEmu, heightEmu);

For a complete report, create the document before the test steps, append evidence after each successful state, and write it in a cleanup path. If the test fails before a screenshot is available, record the failure separately rather than inserting an empty picture.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Troubleshooting

ClassCastException when casting the driver

The object must implement Selenium’s TakesScreenshot. Use an Appium driver implementation that supports screenshots and cast the actual driver instance, not a wrapper that exposes only a limited interface.

Rank #3
Microsoft Word 2013 Plain & Simple
  • Used Book in Good Condition

The Word file is created but Word reports corruption

Make sure the document is written before its output stream closes and that the same XWPFDocument is not written concurrently. Use try-with-resources as shown, and do not append arbitrary text to the binary .docx stream.

addPicture throws an invalid-format or image error

Ensure the bytes are a real PNG and that the picture type is Document.PICTURE_TYPE_PNG. A Base64 string must be decoded first; passing its characters as if they were PNG bytes will fail.

The image is stretched or extends beyond the page

Recalculate the second EMU dimension from the source aspect ratio. Also account for page margins: a standard page’s usable width is smaller than its paper width.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The screenshot is blank or the wrong screen

  • Wait for navigation, animations, and asynchronous content before capturing.
  • Confirm the current native or web context.
  • Verify that the driver is attached to the intended device and window.
  • Check platform security restrictions. Android’s FLAG_SECURE is an example of a setting that can prevent screenshots; support and behavior vary by platform and driver version.

The screenshot call fails on a protected app

Some applications deliberately block screenshots. Remove the restriction only in an authorized test build or use an approved test environment; do not attempt to bypass a production application’s security controls.

Large documents consume too much memory

BYTES keeps each image in memory until it is inserted and released. For many or very large captures, process one image at a time, avoid retaining byte arrays, and consider the temporary-file route while copying each file immediately. Downsize images only when reduced resolution is acceptable for the evidence.

Native Appium capture versus browser screenshot services

Appium is the right tool when the subject is a native or mobile-web session on a connected device. A browser screenshot API addresses a different workflow: rendering a URL on a remote browser and returning an image or PDF. Do not substitute one for the other when device state, gestures, permissions, or native controls are part of the evidence.

Or skip the browser setup:

For a URL rather than a live Appium device, ScreenshotNeo returns a PNG, JPEG, WebP, or PDF from one request. Its cleanup steps accept cookie or consent banners and remove more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be disabled. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the page verdict and billing status in headers. It also provides an MCP server with take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

See the ScreenshotNeo documentation for output and option details. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Java, Python, and Node.js request examples

If your pipeline needs a hosted URL capture alongside Java-generated Word files, these equivalent calls use the same endpoint.

Python

import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)

Node.js

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

These hosted captures are separate from the Appium code above: they do not capture a connected mobile device’s native screen.

Operational checklist

  • Confirm the desired screen is visible and the correct context is selected.
  • Capture with OutputType.BYTES unless a durable image file is also required.
  • Use PNG type and EMU dimensions in addPicture.
  • Preserve the source aspect ratio and fit within page margins.
  • Close the image stream, document, and output stream with try-with-resources.
  • Keep a copy of any FILE output that must survive the JVM.
  • Check security settings when captures are blank or rejected.

Frequently Asked Questions

Can I insert an Appium screenshot into an existing Word template?

Yes. Open the template with POI, locate or create the target paragraph and run, and call the same addPicture method with the PNG stream and EMU dimensions before writing the modified document.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Does this workflow require saving a PNG first?

No. OutputType.BYTES returns the image in memory, so POI can consume a ByteArrayInputStream directly.

Can one DOCX contain screenshots from multiple devices?

Yes. Append each capture to the same XWPFDocument, adding labels or page breaks as needed, then write the document once.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.