ScreenshotNeo

BlogHow-to

Convert a Webpage to PDF in Java for an Indian Banking Portal

Generate a PDF from an authorized banking portal page with Playwright Java, and handle authentication, rendering, storage, and validation carefully.

By the ScreenshotNeo team4 October 202611 min read

For a page your application is authorized to render, use Playwright for Java with Chromium: open the approved URL in an isolated browser context, wait for the application to finish rendering, validate that the expected page loaded, then call Page.pdf() and write the returned bytes to a controlled destination. The PDF is a rendered snapshot, not an authoritative bank-issued statement or receipt. If the document must be official, use the bank’s own export or document workflow.

For customer-specific pages, implement this only within an institution-approved design. Use the bank’s approved authentication and session handling; do not bypass login, MFA, access controls, or export restrictions. Do not log rendered account details. The bank’s security and compliance teams must decide which controls and regulations apply to the portal and deployment.

1. Confirm the use case and authorization

First establish whether the page is public information, an internal authorized page, or customer-specific content. These cases have different access and data-handling requirements. Confirm that the bank permits rendering and retaining the page as a PDF, and use an allowlist for permitted URLs. A browser session must belong to the correct authorized user and must not be reused across customers.

For regulated entities and covered payment applications, RBI directions discuss secure-by-design practices, threat modelling, application lifecycle security, and security testing. The 2023 IT services outsourcing direction also addresses provider monitoring, customer information confidentiality, need-to-know access, incident reporting, and data-storage terms where applicable. These sources do not determine the applicability of a specific deployment; the institution must assess its own scope and obligations. See the RBI Digital Payment Security Controls and RBI IT Services Outsourcing Direction.

2. Set up Playwright Java

Playwright Java is distributed through Maven modules. The official guide documents Java 8 or higher; choose a currently supported Java and browser combination for production, pin the dependency version, and install the matching Playwright browser runtime and operating-system dependencies on the host. PDF generation in this workflow uses Chromium. Consult the Playwright Java installation guide for the current setup steps and version requirements.

Add the Playwright Java dependency to your Maven project. Replace VERSION with the version selected and pinned by your application:

<dependency>
  <groupId>com.microsoft.playwright</groupId>
  <artifactId>playwright</artifactId>
  <version>VERSION</version>
</dependency>

Install the matching Chromium browser using the Playwright CLI for that dependency version, following the installation guide. Do not assume that a browser installed separately on a developer workstation will match the library version or be available in a production container.

3. Generate a PDF from an authorized page

This Java example handles a public or otherwise already-authorized page. It uses an application-specific readiness selector, checks the final URL and expected content, sets paper and margin options explicitly, and writes the PDF bytes to a caller-selected path. It intentionally does not implement banking authentication: connect the page to the institution’s approved session flow instead of inserting credentials into the sample.

import com.microsoft.playwright.Browser;
import com.microsoft.playwright.BrowserContext;
import com.microsoft.playwright.Page;
import com.microsoft.playwright.Playwright;
import com.microsoft.playwright.options.WaitUntilState;

import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;

public final class BankingPageToPdf {
  public static void main(String[] args) throws Exception {
    if (args.length != 3) {
      throw new IllegalArgumentException(
          "Usage: BankingPageToPdf <approved-url> <ready-selector> <output.pdf>");
    }

    String approvedUrl = args[0];
    String readySelector = args[1];
    Path outputPath = Path.of(args[2]);

    // Validate approvedUrl against an institution-managed host allowlist here.
    // Authenticate only through the institution-approved flow, if required.
    try (Playwright playwright = Playwright.create()) {
      Browser browser = playwright.chromium().launch();
      try {
        BrowserContext context = browser.newContext();
        try {
          Page page = context.newPage();
          page.setDefaultNavigationTimeout(Duration.ofSeconds(45).toMillis());
          page.setDefaultTimeout(Duration.ofSeconds(20).toMillis());

          page.navigate(approvedUrl, new Page.NavigateOptions()
              .setWaitUntil(WaitUntilState.DOMCONTENTLOADED));

          // Prefer an app-specific ready signal over a fixed sleep or network-idle guess.
          page.locator(readySelector).waitFor();

          String finalUrl = page.url();
          if (!finalUrl.startsWith("https://portal.example.bank/")) {
            throw new IllegalStateException("Unexpected final page URL");
          }
          if (page.locator("text=Sign in").count() > 0) {
            throw new IllegalStateException("Page appears to be a login page");
          }

          byte[] pdf = page.pdf(new Page.PdfOptions()
              .setFormat("A4")
              .setPrintBackground(true)
              .setPreferCSSPageSize(true)
              .setMargin(new Page.PdfMargins()
                  .setTop("12mm")
                  .setRight("12mm")
                  .setBottom("12mm")
                  .setLeft("12mm")));

          Path parent = outputPath.toAbsolutePath().getParent();
          if (parent != null) {
            Files.createDirectories(parent);
          }
          Files.write(outputPath, pdf);
        } finally {
          context.close();
        }
      } finally {
        browser.close();
      }
    }
  }
}

Example invocation, using an approved URL and a selector that the portal’s page exposes only when the required content is ready:

java BankingPageToPdf \
  'https://portal.example.bank/approved-page' \
  '[data-page-ready="true"]' \
  '/controlled-output/page.pdf'

Replace the example host, readiness selector, and output path. The URL check in the sample is illustrative: implement a strict host and scheme allowlist appropriate to the institution. Do not rely on a broad suffix check that can accept attacker-controlled lookalike hostnames.

4. Choose the rendering and PDF options

Page.pdf() returns PDF bytes and uses print CSS media by default. Its defaults may not match the intended output, so select options deliberately and verify the result against representative pages. The Playwright Java Page API documents the available options; check the API for the version deployed.

Option When to use it Considerations
setFormat("A4") Use a standard paper size such as A4 when that is the required document format. Paper format and CSS page rules can interact. Validate page count, scaling, and clipping.
setMargin(...) Set explicit top, right, bottom, and left margins when a predictable printable area matters. Use units such as mm or in; compare with the page’s own print stylesheet.
setPrintBackground(true) Enable when essential visual information is conveyed by background colors or images. Background printing is off by default. Enabling it may increase output size and may expose decorative content that the print stylesheet would otherwise omit.
setPreferCSSPageSize(true) Let the page’s CSS @page size take priority. CSS page size does not take priority by default. Choose between explicit format and CSS-controlled sizing based on the portal’s intended print layout.
page.emulateMedia(...) Use screen media when the screen-styled layout is specifically required. PDF generation uses print media by default. Emulate screen media before calling pdf() when needed, and validate the screen layout on paper.
Scale and page ranges Fit or limit output when the documented option suits the task. Scaling can make text too small; page ranges can omit required material. Validate against the source page and expected record.
Tagged PDF and outlines Use when the API version provides them and they suit the document workflow. A tagged-output option alone does not prove accessibility conformance. Inspect and validate the generated file for its intended audience and use.

CSS can also affect page breaks and printed content. If the portal’s print stylesheet is authoritative, test with CSS page-size preference and its print media rules. If the requirement is to preserve the screen layout, emulate screen media explicitly. Do not apply custom print CSS to customer pages unless the institution approves the change and the output remains accurate.

5. Handle readiness, authentication, and page state

A successful navigation event does not prove that the relevant account content has loaded. Banking pages can redirect to sign-in, show an authorization error, render data after an API call, or display a partial page while requests continue. Define a safe, application-specific ready condition and validate expected page state before exporting.

  • Use the bank-approved authentication and MFA flow. Do not automate around MFA, export restrictions, or access controls.
  • Use a fresh browser context per isolated job or authorized user boundary. Avoid cross-customer storage-state reuse.
  • Use a host allowlist and reject unexpected redirects before producing a document.
  • Wait for a stable page-specific selector or documented application signal. A fixed delay may be too short on a slow response and unnecessarily long on a fast one.
  • Check for login redirects, error states, and missing expected content without collecting sensitive text into logs.
  • Test pages with dynamic content, localized strings, web fonts, and long tables. Make sure the page is in its final state before printing.

6. Protect the output and operational data

Treat the PDF and browser artifacts as sensitive customer data when they contain account information. Write only to a destination approved for that classification. Apply least-privilege access, encryption, retention and deletion rules, and controls on temporary files. Avoid including page text, cookies, authorization headers, full URLs with sensitive parameters, or PDF bytes in application logs and diagnostics.

Use isolated worker processes or equivalent boundaries where required by the bank’s architecture. Limit concurrency to the capacity of the browser workers and the portal. If browser rendering or document storage uses a third-party service, assess that relationship and its data handling under the institution’s current obligations and policy. The RBI outsourcing direction is relevant where applicable, but it does not replace an institution-specific review.

7. Validate the generated PDF

Validate representative pages before enabling the feature for users. A PDF can be syntactically valid while still missing content or being unsuitable for its intended use.

  • Check that the output opens and contains the expected number of pages.
  • Review clipping, page breaks, repeated headers, table rows, margins, and page orientation.
  • Check fonts and language glyphs, especially for localized names and amounts.
  • Confirm that the selected print or screen media matches the approved output design.
  • Verify that expected content is present and login, error, or incomplete states are rejected.
  • Validate accessibility against requirements for the intended document. A tagged-PDF setting is not proof of conformance. The Indian government accessible PDF process document offers contextual guidance, but does not establish that a particular generated banking PDF complies.
  • Keep the PDF’s status clear: a browser-generated copy is not an official bank-issued statement or transaction record unless the bank’s own workflow explicitly makes it so.

8. Troubleshooting

Symptom Likely cause Fix
Browser launch fails The matching Playwright browser or operating-system dependencies are missing, or the deployed browser does not match the library setup. Install the browser runtime and dependencies using the official guide for the pinned Playwright version. Check the worker image and runtime permissions.
PDF call fails or is unsupported The workflow is not using Chromium, or the deployed API/runtime version differs from the code assumptions. Use the documented Chromium workflow for PDF generation and check the API for the deployed version.
PDF is blank or incomplete The page was printed before application data rendered, a redirect led to another page, or a selector did not represent the full readiness condition. Wait for a page-specific ready signal, validate final URL and expected state, and reject login or error pages.
PDF shows sign-in or access denied The approved session was absent, expired, or not authorized for that page. Use the institution-approved authentication flow and verify access before printing. Do not bypass access controls.
Backgrounds or colors are missing Print backgrounds are disabled by default, or print CSS intentionally removes them. Enable print backgrounds only if needed and approved; inspect print CSS and compare representative output.
Content is clipped or unexpectedly scaled Paper format, margins, CSS @page rules, or scale settings conflict. Choose whether CSS or explicit format governs page size, set margins intentionally, and validate long and wide content.
Fonts or non-Latin glyphs are missing The rendering environment lacks a font or the web font had not loaded when printing. Provide the approved fonts in the browser environment, wait for the page’s font-ready condition, and verify output glyphs.
Output contains stale or wrong-user content Browser context or session state was reused across user boundaries, or a stale page was captured. Use isolated contexts and session lifecycle controls, bind each job to its authorized identity, and validate page state before output.
PDF file is inaccessible or incorrectly tagged Tagged output was not enabled or the generated tags do not satisfy the relevant accessibility requirements. Use the API option if available, then inspect and validate the document against the applicable requirements; do not infer conformance from the flag.

9. Performance, reliability, and cost

Browser rendering has a deployment cost: each worker needs the Java runtime, Playwright’s matching browser, and operating-system dependencies. Page complexity, loaded assets, fonts, network conditions, and concurrent jobs affect completion time and resource use. The sources do not establish a universal throughput figure, so size worker pools with measurements from the institution’s approved environment and representative pages.

For reliability, set navigation and selector timeouts, validate the final URL and application state, and capture only after readiness. Classify failures without logging account content. Retry only transient failures, with bounded attempts and a fresh isolated page or context as appropriate; avoid duplicate exports or repeated actions that could affect portal state. Track operational counts and failure categories while keeping sensitive page data out of telemetry.

Cost includes browser-worker compute, deployment and maintenance, security review, output storage, and retention operations. If evaluating a Java HTML-to-PDF library or a bank-provided export endpoint, compare JavaScript rendering fidelity, content availability, authentication and MFA handling, browser deployment burden, print CSS, language and font behavior, accessibility validation, official document status, data handling, licensing, support, and total operating cost. The available sources document Playwright’s API but do not establish a universal winner for every portal.

Or skip the browser setup

For an authorized page that can be accessed by the API, ScreenshotNeo provides a website screenshot API and MCP server. Its PDF API can return a PDF from one GET request. Use only URLs and content your organization is authorized to process, and assess data handling against the bank’s requirements. See the ScreenshotNeo API documentation.

curl -G "https://api.screenshotneo.com/v1/shot" \
  -d access_key=YOUR_API_KEY \
  --data-urlencode url=https://stripe.com \
  -d format=pdf \
  -o page.pdf
import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={
        "access_key": "YOUR_API_KEY",
        "url": "https://stripe.com",
        "format": "pdf",
    },
    timeout=90,
)
r.raise_for_status()
open("page.pdf", "wb").write(r.content)
const q = new URLSearchParams({
  access_key: 'YOUR_API_KEY',
  url: 'https://stripe.com',
  format: 'pdf',
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`ScreenshotNeo request failed: ${res.status}`);
await import('node:fs/promises').then(fs => fs.writeFile('page.pdf', Buffer.from(await res.arrayBuffer())));

In this example, replace the target with an approved URL. Cookie banners, popups, and chat widgets are removed before the shot; bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card, and paid plans start at $5 for 3,000. Sign up for 1,000 free screenshots a month with no card.

FAQ

Can this create an official bank statement?

No. A browser-generated PDF is a snapshot. Use the bank’s own statement or transaction export when an official record is required.

Can I use the same browser context for several customers?

Do not share session state across customer boundaries. Use the isolation and session lifecycle design approved by the institution.

Does enabling tagged PDF guarantee accessibility?

No. The option is a rendering feature, not proof of conformance. Validate the resulting document against the requirements for its intended audience and use.

Should I wait for network idle before printing?

Not as a universal rule. Use a page-specific readiness condition that represents completed and correct content for the portal; network activity alone may not indicate that state.

Sources