• 15 апреля стартует «Курс «SQL-injection Master» ©» от команды The Codeby

    За 3 месяца вы пройдете путь от начальных навыков работы с SQL-запросами к базам данных до продвинутых техник. Научитесь находить уязвимости связанные с базами данных, и внедрять произвольный SQL-код в уязвимые приложения.

    На последнюю неделю приходится экзамен, где нужно будет показать свои навыки, взломав ряд уязвимых учебных сайтов, и добыть флаги. Успешно сдавшие экзамен получат сертификат.

    Запись на курс до 25 апреля. Получить промодоступ ...

Java, PDF

  • Автор темы Azrael
  • Дата начала

NickProstoNick

Статус как статус :)
Lotus Team
22.08.2008
1 851
27
BIT
0
нет - не пробовал...
но не понял - почему именно так, а не
вот из этого
fo:external-graphic встраивает картинку на страницу, а мне надо прицепить файл целиком. И pdf:embedded-file как раз вроде как позволяет это делать
 

VladSh

начинающий
Lotus Team
11.12.2009
1 784
157
BIT
57
VladSh, такого фидбэка достаточно?
Я ж тут ничо не спрашаю) Имел ввиду, что если спрашивать, то и делиться пропорционально ответам.
Для меня, думаю, буит достаточно. Как буду разбираться, то задам вопросы если не пойму)
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 941
609
BIT
214
fo:external-graphic встраивает картинку на страницу, а мне надо прицепить файл целиком. И pdf:embedded-file как раз вроде как позволяет это делать
прицепить - это как?
-дополнить страницы
-вставить страницы
-вставить ссылку, дополнить страницы
-вставить ссылку, оставить на диске
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 941
609
BIT
214
конвертация разных документов (форматы поддерживаемые open/libreoffice) рапером, через libreoffice
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 941
609
BIT
214
конвертация в ПДФ:
- jodconverter описан по ссылкам (выше), недостаток - присут. ЛО/ОО, за кот. надо следить (экземпляр может "залипнуть"). Точность воспроизведения зависи от документа/присут. шрифтов (исследованиями не занимался)
- , шрифты (идут в составе) устанавливаются на документ сервер и конвертация более/менее , похоже использует механизмы ЛО/ОО (заметил одинаковый рендерер смещения в таблице). Работает по http , сам требует доступа к конвертируемому документу по http. При интенсивной нагрузке тупит (у меня, в виртуаллке, на 4-х ядрах, таймаут приходит при >10-ти потоках одновременно). Я, в текущий момент, использую этот конвертор (наименее сложный в установке/настройке/поддержке)
- xdocperport - конвертация страдает в части наложения графических объектов (скорее-всего старый код конвертора). Трудно подобрать версию POI (по отзывам на стековерфло и моему опыту - 3.17 с xdocreport 2.0.1), скорость так-себе, шрифты нужны для iText, но я даже заморачиваться не стал, с учетом перечисленного.
НО в качестве подстановки по шаблонам - мне он подошел идеально
- - идеальное совпадение с МСО ( в системе, залил в , в ) в моих тестах, платный
Т.о. для качественной и быстрой конвертации - apose, стоит от 1Кбакса. М.б. купят на офис (если бюжет на зажмут ;) )
 
Последнее редактирование:

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 941
609
BIT
214
несколько слов про ПДФ "преобразования"
все знают про iText и что он стал коммерческим...
для "простых" задач, и где нужна бесплатность, я использую PDFBox:
- получение в виде таблицы текста из области документа
- разделение на страницы
- сохранение в виде картинок
- включение картинок в страницы

первую задачу я решал со спецификой и код чистить/модифицировать лень
для остальных:
Java:
package org.lmike;

import org.apache.pdfbox.multipdf.Splitter;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.rendering.ImageType;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.apache.pdfbox.tools.imageio.ImageIOUtil;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;

public class RecognitionsPDFBox implements IRecognitions{
    @Override
    public List<File> split(File file) throws IOException {
        return split(file,dpi);
    }

    public List<File> split(File file, int dpi) throws IOException {
        System.setProperty("sun.java2d.cmm", "sun.java2d.cmm.kcms.KcmsServiceProvider");
        List<File> res=new ArrayList<>();
        Path tempDir= Files.createTempDirectory("images_");
        System.out.println("Temp dir:"+tempDir.toString());
        PDDocument document = PDDocument.load(file);
        PDFRenderer pdfRenderer = new PDFRenderer(document);
        int pageCounter = 0;

        //splitting the pages of a PDF document
        Splitter splitter = new Splitter();
        List<PDDocument> lstPages = splitter.split(document);

        for (PDPage page : document.getPages())
        {
            // note that the page number parameter is zero based
            BufferedImage bim = pdfRenderer.renderImageWithDPI(pageCounter, dpi, ImageType.RGB);

            // suffix in filename will be used as the file format
            PDDocument pdDocument=lstPages.get(pageCounter);
            String fileName=tempDir+"/page_" + (pageCounter++);
            pdDocument.save(fileName+".pdf");
            pdDocument.close();
            fileName+= ".png";
            ImageIOUtil.writeImage(bim, fileName, dpi, 1f);
            res.add(new File(fileName));
        }
        document.close();
        return res;
    }

}
Java:
package org.lmike;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;

import java.io.File;
import java.io.IOException;
import java.util.List;

public interface IRecognitions {
    int dpi=200;
    float displayDPI=72.0f;
    double INCH_2_CM = 2.54;

    List<File> split(File file) throws IOException;

    /**
     *
     * @param file assume pdf format File
     * @param dpi DPI for image to be converted
     * @return List with result Files
     * @throws IOException
     */
    List<File> split(File file, int dpi) throws IOException;

    default void write2pdf(File file, String pdfFilename) throws IOException{
        try (PDDocument doc = new PDDocument()) {
            PDPage page = new PDPage(PDRectangle.A4);
            doc.addPage(page);
            PDImageXObject pdImage = PDImageXObject.createFromFile(file.getAbsolutePath(), doc);
            try (PDPageContentStream contentStream = new PDPageContentStream(doc, page, PDPageContentStream.AppendMode.APPEND, true, true)){
                float scale = displayDPI/ dpi;//1f;
                contentStream.drawImage(pdImage, 20, 20, pdImage.getWidth() * scale, pdImage.getHeight() * scale);
            }
            doc.save(pdfFilename);
        }
    }
}
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 941
609
BIT
214
отступление про aspose (коммерческий продукт)
С практикой его использования могу отметиить возможности (использовал активно):
- распознавание образов (насколько это касается каких продуктов - лучше на сайт)
- деление на страницы/соединение/вставка
- поддержка всяких PDF/A (актуально для госов)
- замена текста (типа что - на что), если в самом ПДФ есть особенности (с позиционированием переносов текста), то при конвертации в docx (одна строка кода) - вопрос снимается (регэкспы, шаблоны, кастомные варианты)
- конвертация между форматами
- распоснавание баркодов (при любой ориентации страницы, перекошенном скане и в разрешении 72dpi)
- дергать текст, графику - легко
будут интересовать подробности - спрашивайте, я не рекламирую продукт - я им тупо пользуюсь
 
Последнее редактирование:

garrick

Lotus Team
26.10.2009
1 351
151
BIT
187
несколько слов про ПДФ "преобразования"
все знают про iText и что он стал коммерческим...
для "простых" задач, и где нужна бесплатность, я использую PDFBox:
LGPL and MPL форк iText 4 https://github.com/LibrePDF/OpenPDF
И многие успешно продолжают пользоваться iText 2.17 у которого была нормальная лицензия, но сам автор говорит, что там не всё чисто с кодом.
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 941
609
BIT
214
LGPL and MPL форк iText 4 https://github.com/LibrePDF/OpenPDF
И многие успешно продолжают пользоваться iText 2.17 у которого была нормальная лицензия, но сам автор говорит, что там не всё чисто с кодом.
помимо лицензии там и сам способ формирования не всегда дает желаемый результат...
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 941
609
BIT
214
бывает нужно преобразовать html в PDF
бесплатный способ :)
XML:
        <!-- https://mvnrepository.com/artifact/org.xhtmlrenderer/flying-saucer-pdf-openpdf -->
        <dependency>
            <groupId>org.xhtmlrenderer</groupId>
            <artifactId>flying-saucer-pdf-openpdf</artifactId>
            <version>9.1.20</version>
        </dependency>
это либа GitHub - flyingsaucerproject/flyingsaucer: XML/XHTML and CSS 2.1 renderer in pure Java для конвертации
нужны ещё шрифты (иначе будут ANSI кракозябры)
Java:
//......
xhtmlToPdf(document.html(), path.toFile());
//.....
    static void xhtmlToPdf(String xhtml, File outputPdf) throws IOException {
        ITextRenderer renderer = new ITextRenderer();
        SharedContext sharedContext = renderer.getSharedContext();
        sharedContext.setPrint(true);
        sharedContext.setInteractive(false);
        sharedContext.setReplacedElementFactory(new ImageReplacedElementFactory());
        sharedContext.getTextRenderer().setSmoothingThreshold(0);
//*** Здесь у меня мудрёж с подгрузкой шрифтов из ресурсов
        //InputStream is=UpdatesListener.class.getResourceAsStream("/local.properties");
        InputStream is=UpdatesListener.class.getResourceAsStream(FONT_PATH);
        File file=StreamTTF.stream2file(is);
        //URL url=UpdatesListener.class.getResource(FONT_PATH);//"/OpenPDF/Gabriola.ttf");
        renderer.getFontResolver().addFont(file.getAbsolutePath()//url.getPath()
                ,BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
                //, true);//"F:\\knpcode\\Java\\Java Programs\\PDF using Java\\OpenPDF\\Gabriola.ttf", true);
/*
        String baseUrl = FileSystems.getDefault()
                .getPath("F:\\", "knpcode\\Java\\", "Java Programs\\PDF using Java\\OpenPDF")
                .toUri()
                .toURL()
                .toString();
*/
        ////for separate files only
        //String baseUrl=UpdatesListener.class.getResource("/OpenPDF").toString();
        renderer.setDocumentFromString(xhtml);//, baseUrl);
        renderer.layout();
        OutputStream outputStream = new FileOutputStream(outputPdf);
        renderer.createPDF(outputStream);
        System.out.println("*INFO* PDF creation completed");
        // put this in finally
        outputStream.close();
        file.delete();
    }
я ещё использую шаблонизатор для подстановки CSS (т.к. либа это позволяет)
XML:
        <!-- https://mvnrepository.com/artifact/org.freemarker/freemarker -->
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.31</version>
Java:
//.....
                    final org.jsoup.nodes.Document document = Jsoup.parse(
                            htmlFromTemplate("template.html"
                                    , result.htmlTable)
//.....
    String htmlFromTemplate(String fName, String body) throws IOException, TemplateException {
        // Конфигурация
        Configuration cfg = new Configuration(Configuration.VERSION_2_3_27);
        final ClassTemplateLoader loader = new ClassTemplateLoader(UpdatesListener.class, "/");
        cfg.setTemplateLoader(loader);
        cfg.setDefaultEncoding("UTF-8");
        cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);

// модель данных
        Map<String, Object> root = new HashMap<>();
        root.put("body", body);
// шаблон
        //UpdatesListener.class.getResource("/"+fName);
        Template temp = cfg.getTemplate(fName);
        //Template temp = cfg.getTemplate(UpdatesListener.class.getResource("/"+fName).getPath());
// обработка шаблона и модели данных
        ByteArrayOutputStream bos=new ByteArrayOutputStream();
        Writer out = new OutputStreamWriter(bos);
        temp.process(root, out);
        out.close();
        return new String( bos.toByteArray(), StandardCharsets.UTF_8 );
    }
пример для верстки (откуда драл CSS - не помню)
HTML:
<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Stock</title>
    <style type="text/css">
        body{background-color: powderblue;}
        * {
            font-family:"Ubuntu Mono";
            /* Gabriola; */
            /* Ubuntu; */
            /*  font-family: Times New Roman; - alternative. Without ""! */
        }
        /*

        @font-face {
            font-family: myFont;
            src: url("../OpenPDF/Gabriola.ttf");
        }
        .fontclass{
            font-family: myFont;
        }
        */
        @Page {
            size: 210mm 297mm;
            margin: 10mm;
        }
        /*
        .myclass{
            font-family: Helvetica, sans-serif;
            font-size:10em;
            font-weight: normal;
            color: blue;
        }
        */
        .tg  {border-collapse:collapse;border-spacing:0;}
        .tg td{border-color:black;border-style:solid;border-width:1px;
            overflow:hidden;padding:10px 5px;word-break:normal;
            font-weight:normal;font-family:"Ubuntu Mono",sans-serif;}
        .tg th{border-color:black;border-style:solid;border-width:1px;
            font-weight:normal;overflow:hidden;padding:10px 5px;word-break:normal;
            font-family:"Ubuntu Mono", sans-serif;}
        .tg .tg-0pky{border-color:inherit;text-align:left;vertical-align:top}
        .tg .tg-0lax{text-align:left;vertical-align:top}
        .tg .tg-dmmf{text-align:right;vertical-align:top}

    </style>
<!--<link href="css/mystyles.css" rel="stylesheet" >-->
</head>
<body>
${body}
</body>
</html>
 
  • Нравится
Реакции: oshmianski

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 941
609
BIT
214
предметный кусок - где я формирую хтмл с выше-перечислегными стилями
Java:
                String htmlTblheader= showStock?
                        String.format("<thead>\n" +
                                        "  <tr>\n"
                                        +"    <th class=\"tg-0pky\">%s</th>\n"
                                        +"    <th class=\"tg-0pky\">%s</th>\n"
                                        +"    <th class=\"tg-0pky\">%s</th>\n"//stock
                                        +"    <th class=\"tg-0pky\">%s</th>\n"
                                        +"  </tr>\n"
                                        +"</thead>"
                                ,M_CODE
                                ,M_NAME
                                ,M_STOCK
                                ,Q_TY
                        )
                        :String.format("<thead>\n" +
                                        "  <tr>\n" +
                                        "    <th class=\"tg-0pky\">%s</th>\n" +
                                        "    <th class=\"tg-0pky\">%s</th>\n" +
                                        "    <th class=\"tg-0pky\">%s</th>\n" +
                                        "  </tr>\n" +
                                        "</thead>"
                                ,M_CODE
                                ,M_NAME
                                ,Q_TY
                        );
                String htmlColGroup=
                        "<colgroup>\n" +
                                "<col style=\"width: 96px\">\n" +
                                "<col style=\"width: 361px\">\n" +
                                (showStock?"<col style=\"width: 96px\">\n":"") +
                                "<col style=\"width: 114px\">\n" +
                                "</colgroup>";

                String htmlTable="<table "
                        +" class=\"tg\" style=\"undefined;table-layout: fixed; width: 571px\""
                        +">"
                        +htmlColGroup
                        +htmlTblheader
                        +"<tbody>"
                        +result.stream()
                        .map(e->
                                showStock?
                                        String.format(
                                                "<td class=\"tg-0lax\">%s</td>"
                                                        +"<td class=\"tg-0lax\">%s</td>"
                                                        +"<td class=\"tg-0lax\">%s</td>"
                                                        +"<td class=\"tg-dmmf\">%s</td></tr>"
                                                ," "+e.getMaterialNumber()
                                                ," "+e.getMaterialDescription()
                                                ," "+e.getStockId()
                                                ,(e.getQtyPacks()<0?0:e.getQtyPacks())+" ")                                    :String.format(
                                "<td class=\"tg-0lax\">%s</td>"
                                        +"<td class=\"tg-0lax\">%s</td>"
                                        +"<td class=\"tg-dmmf\">%s</td></tr>"
                                ," "+e.getMaterialNumber()
                                ," "+e.getMaterialDescription()
                                ,(e.getQtyPacks()<0?0:e.getQtyPacks())+" ")
                        )
                        .collect(Collectors.joining(" \n"))
                        +"</tbody>"
                        +"</table>";
 

garrick

Lotus Team
26.10.2009
1 351
151
BIT
187
Тут есть небольшой учебник
На первый взгляд может показаться весьма поверхностным, но при внимательном изучении можно найти массу полезного - как делать разрывы страниц, как поставить номера страниц, как делать колонтитулы и много чего ещё.
 
  • Нравится
Реакции: lmike

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 941
609
BIT
214
Тут есть небольшой учебник
На первый взгляд может показаться весьма поверхностным, но при внимательном изучении можно найти массу полезного - как делать разрывы страниц, как поставить номера страниц, как делать колонтитулы и много чего ещё.
спасибо, для меня это факультативно - ибо есть аспоз
ну а другим - вполне пригодится
 

evgenyum

Member
17.09.2019
12
0
BIT
44
Добрый всем день!
Использую itext еще древней версии 2.0.6. Через LS2J вызываю функцию, которая в pdf файл вставляет текст. Шрифты беру из каталога Windows\Fonts. А проблема в том, что на моем компьютере все работает, никаких ошибок и падений (ни одного раза не было, тьфу...). А у некоторых пользователей не работает, просто падает клиент с выдачей своего стандартного сообщения о падении. Самое интересное то, что в очень редких случаях клиент может и не упасть и код отработает как положено. Мистика...
А падает на такой функции:
Visual Basic:
FontFactory.getFont("c:\\windows\\fonts\\arialnb.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED, 7f, Font.NORMAL, Color.BLUE);
Либо на такой функции:
Visual Basic:
FontFactory.registerDirectories();

Это два разных варианта. В первом варианте я не вызываю функцию FontFactory.registerDirectories()
При любом варианте падает клиент. И получается падает, как я понимаю, именно при попытке чтения/загрузки шрифта.
Аппаратные характеристики компьютера у тех пользователей где падает клиент такие же как и у меня (Точно не хуже). Все должно быть практически одинаково настроено в системе. В Notes.ini выставлена переменная JavaMaxHeapSize=512MB как у меня так и у пользователей.
Версия клиента Notes 11.0.1 fp4
ОС: Windows 10 Pro

Какие можете дать предположения по краху клиента?
 

garrick

Lotus Team
26.10.2009
1 351
151
BIT
187
Первое, что приходит на ум - нет такого файла со шрифтом. Попробуйте файл mtsans_w.ttf, он лежит в каталоге Notes на клиенте. На сервере такого файла нет.
Второе, если код, что я вижу, на LotusScript, то BaseFont.IDENTITY_H, BaseFont.EMBEDDED, Font.NORMAL, Color.BLUE нужно заменить на конкретные значения (цифры скорее всего).
Третье - что-то с правами доступа. Если это так, первый совет может помочь.

Версию iText можно попробовать 2.17 - её все используют.
 

evgenyum

Member
17.09.2019
12
0
BIT
44
Первое, что приходит на ум - нет такого файла со шрифтом. Попробуйте файл mtsans_w.ttf, он лежит в каталоге Notes на клиенте. На сервере такого файла нет.
Второе, если код, что я вижу, на LotusScript, то BaseFont.IDENTITY_H, BaseFont.EMBEDDED, Font.NORMAL, Color.BLUE нужно заменить на конкретные значения (цифры скорее всего).
Третье - что-то с правами доступа. Если это так, первый совет может помочь.

Версию iText можно попробовать 2.17 - её все используют.
Шрифты все есть, проверял. К тому же у всех стоит одна и та же Win10Pro по корпоративной политике.
Даже если допустить, к примеру, что шрифта нет, почему может тогда падать на FontFactory.registerDirectories()?
Тем более в каких-то очень редких случаях (не понял от чего зависит) все отрабатывает без каких-либо падений.
Если бы еще версию 2.17 где-нибудь взять, попробовал бы
 

savl

Lotus Team
28.10.2011
2 597
310
BIT
179
Шрифты все есть, проверял. К тому же у всех стоит одна и та же Win10Pro по корпоративной политике.
Даже если допустить, к примеру, что шрифта нет, почему может тогда падать на FontFactory.registerDirectories()?
Тем более в каких-то очень редких случаях (не понял от чего зависит) все отрабатывает без каких-либо падений.
Если бы еще версию 2.17 где-нибудь взять, попробовал бы
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!