How to Capture Indian GST Invoice Pages as Images with wkhtmltoimage
Use wkhtmltoimage to render an accessible invoice page as an image, tune the output, and understand when the GST Portal’s PDF or data downloads are a better fit.
wkhtmltoimage can render an accessible HTML page or local HTML file to an image. The basic command is wkhtmltoimage 'https://example.invalid/invoice' invoice.png; replace the example URL with a page you are authorized to access and choose an output extension such as .png or .jpg. This is the command shape, not a verified procedure for capturing a signed-in GST Portal page. The tool uses Qt WebKit, and the available documentation does not establish that it can complete the GST Portal’s current login, OTP, scripts, or protected-content flow. [wkhtmltopdf project] [wkhtmltoimage manual]
First identify whether you actually need an image. The GST Portal documents PDF and JSON downloads for e-invoices, and separate Excel detail and PDF summary downloads in the GSTR-1 workflow. These are different outputs from a screenshot of a rendered web page. [GST Portal e-Invoice JSON download guide] [GST Portal GSTR-1 guide]
1. Choose the right GST invoice output
Use the portal’s download workflow when the requirement is the official digital invoice or return data. Use wkhtmltoimage when the requirement is specifically an image of an HTML page that the renderer can access. Converting a downloaded PDF or spreadsheet to an image is a separate workflow; wkhtmltoimage is documented as an HTML-to-image converter.
| What you need | Documented route | What to keep in mind |
|---|---|---|
| Generated or received e-invoice document | The GST Portal e-Invoice guide describes PDF and JSON downloads. | Follow the relevant taxpayer workflow and check the current portal interface. A downloaded invoice is not a screenshot. |
| E-invoice details in GSTR-1 | The GSTR-1 guide describes downloading e-invoice details in Excel. | This is return data, not an image of an individual invoice page. |
| GSTR-1 summary | The GSTR-1 guide describes a PDF summary. | A return summary PDF may not contain the particular invoice view you need. |
| Image of an accessible HTML page | Render the page URL or local HTML with wkhtmltoimage. |
Whether a current authenticated GST Portal page renders successfully is not established by the tool documentation. |
2. Install and check wkhtmltoimage
Install a build appropriate for your operating system using a source you trust, then check that the executable is available in your shell. The upstream project describes its command-line tools as headless HTML renderers based on Qt WebKit. Its GitHub repository is archived and read-only as of January 2, 2023; that status applies to that repository and does not establish the status of every package or fork. [Upstream project repository] [Project website]
wkhtmltoimage --version
wkhtmltoimage --help
If the shell reports that the command is unavailable, install the executable or add its installation directory to your PATH. Check which binary and version your environment is actually invoking before comparing results across machines.
3. Capture an accessible invoice page
The manual’s syntax is wkhtmltoimage [OPTIONS]... <input file> <output file>. Quote a URL so shell characters are not interpreted, and use a URL that the machine running the command can reach without interactive authentication.
wkhtmltoimage 'https://example.invalid/invoice' invoice.png
For an image encoded as JPEG, give the output a .jpg extension and set the format explicitly if needed:
wkhtmltoimage --format jpg --quality 90 'https://example.invalid/invoice' invoice.jpg
To render a local HTML file, pass its path as the input:
wkhtmltoimage ./invoice.html invoice.png
The URL and local-file examples are templates. Replace the sample inputs with your own authorized page or file. A successful process exit alone does not prove the image includes all invoice content; open the output and inspect it.
4. Tune the capture
Start with the default rendering. Change one setting at a time so you can tell whether it fixes cropping, readability, or page timing.
| Need | Option | Example or behavior |
|---|---|---|
| Guide the page’s viewport width | --width <pixels> |
--width 1400. The manual calls this a guideline; use --disable-smart-width to make width strict. |
| Set screen height | --height <pixels> |
Height defaults to a value calculated from page content. |
| Crop to a rectangle | --crop-x, --crop-y, --crop-w, --crop-h |
Coordinates and dimensions define the crop region. Check that totals and other required fields remain inside it. |
| Choose image format | --format <format> |
Use a format supported by the installed build and a matching filename extension. |
| Adjust JPEG compression | --quality <0-100> |
Applies image quality control; the manual gives a range from 0 to 100. |
| Control JavaScript | --enable-javascript or --disable-javascript |
Disabling JavaScript can leave script-rendered content absent. Enabling it does not guarantee that a modern application will work in this renderer. |
| Wait after page load | --javascript-delay <milliseconds> |
For example, --javascript-delay 2000 waits two seconds for scripts to finish. |
| Wait for a page status | --window-status <value> |
Waits until window.status equals the supplied string. The page must set that value. |
| Set zoom | --zoom <factor> |
Changes the rendering scale; inspect text size and crop afterward. |
| Load or omit images | --images or --no-images |
Use image loading when invoice marks or a QR code are part of the required view. |
| Read local assets for a local HTML file | --allow <path> or local-file access options |
Allow only the needed directory. The manual documents disabling local file access and selectively allowing paths. |
Example with a wider viewport and a short rendering delay:
wkhtmltoimage --width 1400 --javascript-delay 2000 'https://example.invalid/invoice' invoice.png
For an intentionally fixed-width capture:
wkhtmltoimage --width 1400 --disable-smart-width 'https://example.invalid/invoice' invoice.png
For a cropped image, provide values that match the page’s rendered coordinate system:
wkhtmltoimage --crop-x 40 --crop-y 80 --crop-w 1100 --crop-h 1500 'https://example.invalid/invoice' invoice.png
Exact layout depends on the input page, loaded assets, renderer build, fonts, viewport, and timing. The command manual documents these controls, but does not promise that a particular GST page will render as expected. [wkhtmltoimage options]
5. Capture local HTML or a page that needs custom resources
For a local invoice template that loads CSS, fonts, or images from nearby files, allow only the directory containing those resources. Avoid enabling broad local-file access without a specific need.
wkhtmltoimage --disable-local-file-access --allow ./invoice-assets ./invoice.html invoice.png
The manual also documents repeatable custom headers and cookies. These are renderer options, not evidence that a protected GST Portal session can be reproduced. Never put passwords, OTPs, session cookies, or other credentials in a command that may be stored in shell history, logs, or shared scripts. Use only access methods you are authorized to use, and do not share secrets in a screenshot job or command example.
wkhtmltoimage --custom-header 'Accept-Language' 'en' 'https://example.invalid/invoice' invoice.png
For pages whose content is controlled by your own application, you can wait on a status value only if the page sets it. Example option shape:
wkhtmltoimage --window-status invoice-ready 'https://example.invalid/invoice' invoice.png
6. Verify the result before using it
- Open the generated file and confirm it is not blank or an error page.
- Check that invoice identifiers, supplier and recipient details, taxable values, tax amounts, totals, and any QR code you need are visible and legible.
- Check the top and bottom edges for clipped content, especially when using a crop or strict width.
- Confirm that the output format is the one your next system accepts.
- Keep the original portal download or source file when you need the official PDF, JSON, or return data; an image capture is a rendered view.
7. Common problems and fixes
| Symptom | Likely cause | What to try |
|---|---|---|
| Command not found | The executable is not installed or is outside PATH. |
Install a suitable build and check wkhtmltoimage --version. |
| Blank page or missing invoice data | The content may require JavaScript, an interactive session, or protected access; it may also load after capture starts. | For a page you control, try enabling JavaScript and a modest delay or a page status wait. For GST Portal access, use its documented download flow if appropriate; renderer compatibility with the current authenticated page is unverified. |
| Login page or access denied instead of invoice | The renderer did not obtain the required interactive or authenticated access. | Do not assume cookies or headers will reproduce the browser session. Use an authorized portal download route or a page that is accessible to the renderer. |
| Image is too narrow or content is clipped | Viewport width or crop dimensions do not match the page layout. | Increase --width, test --disable-smart-width if strict width is needed, and remove or revise crop options. |
| Text or QR code looks blurry | The rendered scale or output dimensions may be too small, or JPEG compression may be too aggressive. | Increase viewport width or zoom, use PNG where appropriate, or raise JPEG quality. Recheck file size and legibility. |
| Images, styles, or fonts are missing | Assets may be blocked, inaccessible, unavailable to the local file renderer, or not loaded before capture. | Check asset URLs and local paths. For local files, allow only the specific resource directory. Confirm the page can load those resources from the same machine. |
| Output file is missing or empty | The input failed to load, output path is not writable, or rendering aborted. | Check the command’s error output, input URL, destination permissions, and --load-error-handling setting. Do not treat “ignore” or “skip” as proof of a complete image. |
| Local HTML cannot read companion files | Local-file access restrictions block related assets. | Use --allow for the narrow asset directory or adjust local-file access only when you understand the files being exposed. |
| Results differ across machines | Different binary builds, fonts, network access, page state, or timing can change rendering. | Record the binary version and rendering options, and make the page’s inputs and assets consistent where you control them. |
8. Performance, reliability, and cost
wkhtmltoimage runs headlessly, so it does not require a display service according to the upstream project. Render time and output size depend on the page, image assets, viewport, and delays; the cited sources give no benchmark for GST invoice pages. A longer JavaScript delay can allow a slow page more time to render, but it also adds time to every capture. A wide viewport and high-quality image can make output larger. Choose dimensions and format based on the downstream need, then inspect the image.
For reliable repeated captures, use pages you control or supported download paths, keep the renderer build and options consistent, set explicit output paths, and handle command failures. Treat a renderer’s ability to reach a public URL separately from its ability to pass an interactive login or render modern application behavior. The upstream GitHub repository is archived; check package and fork status before relying on a particular distribution for ongoing production work. [Repository archive notice]
The renderer is open-source software under LGPLv3 according to the upstream project materials. This article makes no claim about the cost of a particular hosted environment, packaging, or support arrangement. [wkhtmltopdf project website]
9. Or skip the browser setup
If the invoice page is reachable at a URL the capture service can access, ScreenshotNeo can return an image with one GET request. See the ScreenshotNeo API documentation for request options.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.invalid/invoice -o invoice.webp
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://example.invalid/invoice"},
timeout=90,
)
open("invoice.webp", "wb").write(r.content)
const q = new URLSearchParams({
access_key: 'YOUR_API_KEY',
url: 'https://example.invalid/invoice'
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
const image = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('invoice.webp', image));
ScreenshotNeo removes cookie banners, newsletter popups, and chat widgets 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; paid plans start at $5 for 3,000 screenshots. These capture features do not establish that the current GST Portal login or protected invoice pages are accessible to the service. Use a URL and access method you are authorized to use. Learn about ScreenshotNeo or sign up for 1,000 free screenshots a month with no card.
10. FAQ
Can wkhtmltoimage download my GST e-invoice directly?
It renders an HTML page to an image. The GST Portal’s documented e-Invoice workflow includes PDF and JSON downloads; use that route when you need those digital invoice files.
Can I turn the GST Portal PDF into a PNG with this command?
wkhtmltoimage takes an HTML page or file as input. The cited manual does not describe PDF-to-image conversion; treat converting a downloaded PDF as a separate step with a suitable PDF conversion tool.
Will adding a cookie make the GST Portal login work?
The manual documents cookie options, but the available sources do not verify the current GST Portal authentication flow with this renderer. Do not put credentials or session secrets in shared commands.
Should I use PNG or JPEG?
Choose the format accepted by your destination and check legibility. The manual exposes a format option and JPEG quality control; it does not prescribe a best format for GST records.
Does this image replace the official invoice?
No. A screenshot is a rendered image of a page. Keep or download the official document or data format required for your workflow.


