Получение высоты таблицы или ячейки в iText 7 [дубликат]

Почему эта ошибка настолько боресома и шумна, просто потому, что она может возникать в различной ситуации.

Я сделал здесь все вышеперечисленные ошибки и все еще сосал. Поэтому убедитесь, что вы сделали то же самое, что и я, прежде чем смотреть вниз.

Возможно, я не могу исправить ситуацию с моментом моментально, , но я могу указать направление или мышление на u (Тот, кто наконец спустился сюда). Я начал задумываться над ошибкой моей запущенной программы, возникшей после того, как я убедился, что имя экземпляра явно правильно, и установите мою базу данных, чтобы позволить удаленное управление, следуя приведенным выше методам. После этого я подозревал, что что-то не так происходит в моем фрагменте кода SQL-соединения.

Решение моей проблемы:

  • Проверьте мою функцию sqlconnection

  • Нажмите, чтобы посмотреть его конфигурацию

  • Новое соединение

  • Выберите имя сервера ur

Он работает для меня с размышлением о том, что именно происходит в процессе соединения. Надеюсь, что мое мышление приведет вас к ошибке ур.

-2
задан Brian Tompsett - 汤莱恩 19 January 2017 в 11:28
поделиться

2 ответа

В iText5 элементы и информация об их позиции / размере были немного смешаны вместе, что позволило вам называть calculateWidths на элементе PdfPTable.

В iText7 эта функция отделена, который позволяет различную гибкость для элементов рендеринга / компоновки.

Таким образом, элементы модели, примером которых является экземпляр Table, ничего не знают об их позиции или размере. Вызов table.getHeight приводит к null, потому что у table не было ранее установленного свойства HEIGHT.

Чтобы вычислить высоту таблицы, нужно было бы использовать функциональность рендеринга.

Для элемента модели вы можете получить поддерево визуализаторов, представляющих этот элемент модели, и все его дочерние элементы, а layout - в любой заданной области. Чтобы действительно знать высоту таблицы, вы хотели бы создать область, которая сознательно будет достаточной для размещения всего содержимого элемента.

PdfDocument pdfDoc = ...
Document doc = ...

Table table = new Table(2)
            .addCell(new Cell().add(new Paragraph("cell 1, 1")))
            .addCell(new Cell().add(new Paragraph("cell 1, 2")));
LayoutResult result = table.createRendererSubTree().setParent(doc.getRenderer()).layout(
            new LayoutContext(new LayoutArea(1, new Rectangle(0, 0, 400, 1e4f))));

System.out.println(result.getOccupiedArea().getBBox().getHeight());

Вышеприведенный код печатает 22.982422O для меня, но результаты могут меняться в зависимости от конфигурации и свойств элементов.

Я хотел бы указать две важные части кода:

  1. Пропускаем 1e4f как высота LayoutArea, учитывая, что этого будет достаточно, чтобы поместить всю таблицу. Обратите внимание: если таблица не может быть помещена на эту высоту, результат никогда не будет превышать эту заданную высоту, и, следовательно, она не будет корректной для вашей usecase (знайте общую высоту таблицы). Поэтому обязательно пропустите высоту, которая будет достаточной для размещения всей таблицы.
  2. .setParent(doc.getRenderer()) часть важна здесь и используется для извлечения наследуемых свойств. Обратите внимание, что мы не задали много свойств для элемента table, даже шрифта, но эта информация необходима, чтобы знать область, в которой этот элемент будет занимать. Таким образом, эта информация будет наследоваться от родительской цепочки во время layout. Вы можете проверить это, изменив шрифт документа: document.setFont(newFont); или размер шрифта: document.setFontSize(24); и просмотрев результирующее изменение высоты
4
ответ дан Alexey Subach 18 August 2018 в 02:48
поделиться

Ну, из-за того, как среда визуализации написана в iText7, пока еще нет способа вычислить высоту объекта макета до его добавления в родительский документ, поскольку фактический расчет высоты для объектов макета происходит, когда они добавляются к объекту Document.

Вы можете передать ретранслиту Document, позволяя изменять содержимое ранее добавленных элементов. Используя это, вы можете имитировать рендеринг таблиц и задерживать их высоты при добавлении новых элементов. table.getHeight() все еще не будет работать, поскольку он извлекает свойство height, и это свойство в настоящее время не установлено нигде в процессе рендеринга таблицы.

В приведенном ниже примере я написал метод удобства который выполняет итерацию над деревом рендеринга и распечатывает область, в которой каждая таблица занимает документ, чтобы показать вам, как вы можете получить рассчитанные высоты.

Сам пример добавляет некоторые документы в документ, отображает занятые области, добавляет некоторые ячейки в каждую таблицу, отображает занятые области (они одинаковы с добавлением к элементу, который был добавлен до того, как он 't запускает макет) и, наконец, вручную запускает ретранслятор и отображает конечные занятые области.

public class DelayedLayout {
    public static String DEST = "target/output/StackOverflow/DelayedLayout/delayed.pdf";

    public static void main(String[] args)throws IOException, FileNotFoundException{
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new DelayedLayout().createPdf(DEST);
    }

    public void createPdf(String dest) throws IOException, FileNotFoundException{
        PdfWriter writer = new PdfWriter(dest);
        PdfDocument pdfDoc = new PdfDocument(writer);
        boolean immediateFlush = false;
        boolean relayout = true;
        //Set immediate layout to false, so the document doesn't immediatly write render-results to its outputstream
        Document doc = new Document(pdfDoc, PageSize.A4,immediateFlush);
        Table tOne = createSimpleTable();
        for(int i= 0; i< 5; i++) {
            //Add a table and some whitespace
            doc.add(tOne);

            doc.add(new Paragraph(""));

        }
        System.out.println("\nInitial layout results");
        printOccupiedAreasOfTableRenderers(doc.getRenderer());
        System.out.println("\nAdding extra cells to the table");
        addToTable(tOne);
        printOccupiedAreasOfTableRenderers(doc.getRenderer());
        System.out.println("\nForcing the document to redo the layout");
        if(relayout)doc.relayout();
        printOccupiedAreasOfTableRenderers(doc.getRenderer());
        doc.close();
    }

    /**
     * Create a very simple table
     * @return simple table
     */
    private Table createSimpleTable(){
        int nrOfCols = 3;
        int nrOfRows = 5;

        Table res = new Table(nrOfCols);
        for(int i= 0; i<nrOfRows;i++){
            for(int j = 0; j<nrOfCols;j++){
                Cell c = new Cell();
                c.add(new Paragraph("["+i+", "+j+"]"));
                res.addCell(c);
            }
        }

        return res;
    }

    /**
     * Add some extra cells to an exisiting table
     * @param tab table to add cells to
     */
    private void addToTable(Table tab){
        int nrOfRows = 5;
        int nrOfCols = tab.getNumberOfColumns();
        for(int i=0; i<nrOfRows*nrOfCols;i++){
            Cell c = new Cell();
            c.add(new Paragraph("Extra cell"+ i));
            tab.addCell(c);
        }

    }

    /**
     * Recursively iterate over the renderer tree, writing the occupied area to the console 
     * @param currentNode current renderer-node to check
     */
    private void printOccupiedAreasOfTableRenderers(IRenderer currentNode){
        if(currentNode.getClass().equals(TableRenderer.class)){
            System.out.println("Table renderer with occupied area: " + currentNode.getOccupiedArea());
        }
        for (IRenderer child:currentNode.getChildRenderers()) {
            printOccupiedAreasOfTableRenderers(child);
        }
    }
2
ответ дан Samuel Huylebroeck 18 August 2018 в 02:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: