Search code examples
javaitext7screen-readersnvdapdfhtml

Problems with itext7 pdfhtml headers and screen readers?


I'm working on iText7 using html to pdf capabilities.

I just noted that Header set on every page has this problem. Header is not read by screen reader. The rest of the document works perfectly with screen reader. I need it for accessibility check.

This is how I set Header:

<html>
<head>
    <link rel="stylesheet" href="{...}pdf/css/style.css" type="text/css" />
    <style>
        #header {
            position: running(header);
        }
        @page {
            margin-top: 100px;
            @top-left {
                content: element(header);
            }
        }
    </style>
</head>
<body>
<div id="header">
    <table width="100%">
        <tr>
            <td colspan="2">&nbsp;</td>
        </tr>
        <tr>
            <td><span class="...">{...}</span></td>
            <td rowspan="2" class="... ..."><span><img src="{...}pdf/images/..." alt="..." /></span></td>
        </tr>
        <tr>
            <td><span class="...">{...}</span></td>
        </tr>
    </table>
</div>...
...
...

Solution

  • For screen reader I did not find any no way to make it work in pure HTML.

    If someone in future have some ideas it will be sure appreciated.

    For now I worked coding the event handler of start new page.

    I'm working on some refinements, but something like this:

    public class SomePdfCreationClass {
    
        public SomeReturnType createPdf {
            ...
            
            Header headerHandler = new Header(String header1, List<String> subHeaders);
            pdf.addEventHandler(PdfDocumentEvent.START_PAGE, headerHandler);
             
            HtmlConverter.convertToPdf(htmlFile, pdf, converterProperties);
            
            writer.close();
            pdf.close();
            
            ...
        }
        
        protected class Header implements IEventHandler {
            
            private String header1;
            private List<String> subHeaders;
    
            public Header(String header1, List<String> subHeaders) {
                this.header1 = header1;
                this.subHeaders = subHeaders;
            }
    
            @Override
            public void handleEvent(Event event) {
    
                try {
                    PdfDocumentEvent docEvent = (PdfDocumentEvent) event;
                    PdfDocument pdf = docEvent.getDocument();
                    PdfPage page = docEvent.getPage();
    
                    PdfDictionary pdfObject = page.getPdfObject();
    
                    PdfCanvas headerPdfCanvas = new PdfCanvas(page.newContentStreamBefore(), page.getResources(), pdf);
                    Rectangle headerRect = new Rectangle(35, 740, 495, 96);
                    Canvas headerCanvas = new Canvas(headerPdfCanvas, pdf, headerRect);
    
                    headerCanvas.setFontProvider(fontProviderService.getFontProvider());
                    PdfFont font = PdfFontFactory.createFont(staticResourcesPath + "...ttf",
                            PdfEncodings.IDENTITY_H, true);
                    headerCanvas.setFontSize(18).setFont(font);
    
                    headerCanvas.enableAutoTagging(page);
                    CreateHeaderContent(headerCanvas);
                    headerCanvas.close();
    
                } catch (IOException e) {
                    ...
                }
            
            }
            
            private void CreateHeaderContent(Canvas canvas) throws MalformedURLException
            {
                Table table = new Table(UnitValue.createPercentArray(new float[] { 80, 20 } ));
                table.setWidth(UnitValue.createPercentValue(100));
        
                Cell cell1 = new Cell().add(new Paragraph(header1).setBold().setFontSize(11).setTextAlignment(TextAlignment.LEFT));
                for (int i = 0; i < subHeaders.size(); i++) {
                    cell1.add(new Paragraph(subHeaders.get(i)).setFontSize(8).setTextAlignment(TextAlignment.LEFT));
                }
                cell1.setBorder(Border.NO_BORDER);
                table.addCell(cell1);
    
                ImageData imageData = ImageDataFactory.create(staticResourcesPath + "...png");
                Image image = new Image(imageData);
                image.getAccessibilityProperties().setAlternateDescription("...");
                Cell cell2 = new Cell().add(image.setTextAlignment(TextAlignment.RIGHT));
                cell2.setBorder(Border.NO_BORDER);
                
                cell2.setVerticalAlignment(VerticalAlignment.MIDDLE);
                table.addCell(cell2);
        
                canvas.add(table);
            }
            
        }
        
    }
    

    Doing this I had to remove html for header:

    <html>
    <head>
        <link rel="stylesheet" href="..." type="text/css" />
    </head>
    <body>
    ...