ShauryaaIBM opened a new pull request, #43762:
URL: https://github.com/apache/superset/pull/43762
### SUMMARY
Replaces the raster-screenshot-stitched PDF path for dashboard reports with
Playwright's native \`page.pdf()\`, producing **vector PDFs with selectable
text**. The feature is strictly additive: it is gated by
\`DASHBOARD_REPORTS_BROWSER_PRINT_PDF\` (default: \`False\`) and any failure
falls back transparently to the existing screenshot path. **No behaviour change
for existing deployments.**
#### How it works
When both \`PLAYWRIGHT_REPORTS_AND_THUMBNAILS\` and
\`DASHBOARD_REPORTS_BROWSER_PRINT_PDF\` are enabled and a dashboard PDF report
runs:
1. \`DashboardPrintScreenshot\` appends \`?print=1&standalone=3\` to the
dashboard URL.
2. Playwright renders at 1600 px viewport so ECharts/canvas elements draw at
their design resolution.
3. The frontend detects \`?print=1\`, adds \`body.print-mode\`, and injects
combined CSS (font-size tier + layout + orientation).
4. A JavaScript pipeline prepares the DOM for \`page.pdf()\`:
- \`UNHIDE_TAB_PANELS_JS\` — removes \`display:none\` from antd CSSMotion
tab panels.
- \`PRINT_ALL_CHART_HOLDERS_READY_JS\` — waits for every chart holder
(including below-fold) to reach a terminal state.
- \`SHOW_ALL_TABLE_ROWS_JS\` — fires \`onChange(0)\` on
client-side-paginated tables to expand all rows.
- \`EXPAND_TABLE_CONTAINERS_JS\` — releases inline
height/overflow/pixel-width constraints. The \`hasInlineWidth\` condition (any
\`width:Xpx\` inline, no overflow precondition) correctly handles the useSticky
header-sizer chain.
- \`MEASURE_TABLE_COLUMNS_JS\` + \`BAND_TABLE_COLUMNS_JS\` — greedy-packs
columns of wide tables into per-page bands (each a standalone \`<table>\` with
key + band columns repeated).
- \`SCALE_WIDE_TABLES_JS\` — CSS \`transform:scale()\` for tables still
overflowing after banding; marks \`data-print-landscape="true"\` in \`auto\`
orientation mode.
- \`SET_PRINT_FONT_SIZE_JS\` — patches \`font-size\` on \`.header-line\`
(Big Number charts use React inline styles that CSS \`!important\` cannot
override). Fires for all three tiers.
- \`ANNOTATE_PRINT_COLUMNS_JS\` — tags columns with flex-grow weights for
optional 2-column layout.
5. Header/footer templates are built. All user-supplied strings are
HTML-escaped. Per-report content overrides global config.
6. \`page.pdf(format="A4", scale=794/1600, print_background=True,
display_header_footer=True)\`.
7. Any exception → \`None\` → falls back to screenshot path.
#### Per-report configuration (Alerts & Reports modal)
Four controls appear when the flag is on and format is PDF for a dashboard:
| Control | Stored in |
|---|---|
| PDF font size (Small / Medium / Large) | \`extra.dashboard.pdf_font_size\`
|
| PDF orientation (Portrait / Landscape / Auto) |
\`extra.dashboard.pdf_orientation\` |
| Use 2-column adaptive layout | \`extra.dashboard.pdf_layout\` |
| PDF header left / right + footer left / center |
\`extra.dashboard.pdf_header\` / \`pdf_footer\` |
Each per-report value overrides the corresponding global config key.
#### Font size tiers (at 1600 px viewport → approx on A4 paper)
| Tier | Table td/th | Chart title | Big Number |
|---|---|---|---|
| small (default) | 16 px (~8 pt) | 22 px (~11 pt) | 48 px (~9 pt) |
| medium | 24 px (~12 pt) | 32 px (~16 pt) | 72 px (~14 pt) |
| large | 36 px (~18 pt) | 44 px (~22 pt) | 108 px (~21 pt) |
#### New config keys
```python
DASHBOARD_REPORTS_BROWSER_PRINT_PDF = False # master switch
BROWSER_PRINT_PDF_FONT_SIZE = None # 'small'|'medium'|'large'
BROWSER_PRINT_PDF_LAYOUT = None # '1col'|'2col'
BROWSER_PRINT_PDF_ORIENTATION = None # 'portrait'|'landscape'|'auto'
BROWSER_PRINT_PDF_VIEWPORT_WIDTH = 1600
BROWSER_PRINT_PDF_HEADER_FOOTER = True
BROWSER_PRINT_PDF_HEADER_CONTENT = {"left": "{title}", "center": "",
"right": "Apache Superset | {date}"}
BROWSER_PRINT_PDF_FOOTER_CONTENT = {"left": "Confidential", "center":
"Generated by Apache Superset"}
```
Header/footer slots support \`{title}\` (HTML-escaped dashboard title) and
\`{date}\` (Chromium date span) tokens.
#### New dependency
\`pypdf>=6.16.2,<7\` added to \`pyproject.toml\` + \`requirements/base.txt\`
for multi-tab PDF merging. The import is inside a \`try/except ImportError\`
block — single-URL render is used if pypdf is unavailable.
### BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
**Before (flag off or Playwright not installed):** PDF reports are produced
by stitching raster PNG screenshots. Text is not selectable; table rows are cut
mid-row at page boundaries; wide tables with many columns are clipped.
**After (flag on):** \`page.pdf()\` vector output. Text is selectable.
Tables expand to show all rows. Wide tables are banded or scaled to fit.
Per-page header (title + date) and footer (confidential notice + page
numbering) are stamped automatically.
### TESTING INSTRUCTIONS
1. Add to \`superset_config.py\`:
```python
FEATURE_FLAGS = {
"PLAYWRIGHT_REPORTS_AND_THUMBNAILS": True,
"DASHBOARD_REPORTS_BROWSER_PRINT_PDF": True,
}
```
2. Install Playwright: \`pip install playwright && playwright install
chromium\`.
3. Create a Report targeting a dashboard, format = **PDF**, trigger it.
4. Verify the attachment is a vector PDF with selectable text.
5. Open the Alerts & Reports modal for that report, set PDF options (font
size, orientation, custom header), re-trigger, and verify the changes take
effect.
6. Disable the flag and confirm the report still works via the screenshot
fallback.
**Automated tests:**
```bash
# Python unit tests (all mocked, no browser)
pytest tests/unit_tests/utils/test_browser_print_pdf.py -v # 31 tests
# Jest tests
cd superset-frontend
npx jest "src/dashboard/components/__tests__/printModeLogic.test.ts"
--no-coverage # 22 tests
```
### ADDITIONAL INFORMATION
- [x] Required feature flags: \`DASHBOARD_REPORTS_BROWSER_PRINT_PDF\`
(default \`False\`) + pre-existing \`PLAYWRIGHT_REPORTS_AND_THUMBNAILS\`
- [x] Changes UI: PDF options block in Alerts & Reports modal (only visible
when flag enabled, format=PDF, content=dashboard)
- [x] Introduces new feature or API: \`DashboardPrintScreenshot\`,
\`WebDriverPlaywright.get_print_pdf()\`, new config keys
- [ ] Has associated issue:
- [ ] Includes DB Migration
- [ ] Removes existing feature or API
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]