IText - HTML для PDF - изображение не отображается в формате PDF - программирование
Подтвердить что ты не робот

IText - HTML для PDF - изображение не отображается в формате PDF

У меня есть html-страница с текстом, изображением, и я разбираю содержимое HTML в iText для создания PDF файла. В сгенерированном PDF-изображении изображения не отображаются, и отображается только текст.

Если я пройду абсолютный путь, например D:/Deiva/CRs/HTMLPage/article-101-horz.jpg, изображение будет напечатано. Но если я попытаюсь распечатать изображение с сервера, например

http://localhost:8085/content/dam/article-101-h1.jpg or http://www.google.co.in/intl/en_ALL/images/logos/images_logo_lg.gif

то он не печатается в PDF.

ПРИМЕЧАНИЕ. Я использую itextpdf-5.2.1.jar для создания PDF файла.

Мой HTML-код (Article.html):

<html>
   <head>
   </head>
   <body>   
     <p>Generate PDF with image using iText.</p>
     <img src="http://localhost:8085/content/dam/article-10-h1.jpg"></img>
     <img src="http://www.google.co.in/intl/en_ALL/images/logos/imgs_logo_lg.gif"></img>
     <img class="right horz" src="D:/Deiva/CRs/HTMLPage/article-101-horz.jpg"></img>
   </body>
</html>

Я использую приведенный ниже код java для создания PDF:

private void createPDF (){

  String path = "D:/Deiva/Test.pdf";
  PdfWriter pdfWriter = null;

  //create a new document
  Document document = new Document();

  try {

   //get Instance of the PDFWriter
   pdfWriter = PdfWriter.getInstance(document, new FileOutputStream(path));

   //document header attributes
   document.addAuthor("betterThanZero");
   document.addCreationDate();
   document.addProducer();
   document.addCreator("MySampleCode.com");
   document.addTitle("Demo for iText XMLWorker");
   document.setPageSize(PageSize.LETTER);

   //open document
   document.open();
   InputStream is = new             FileInputStream("D:/Deiva/CRs/Oncology/Phase5/CR1/HTMLPage/Article.html");

   // create new input stream reader
   InputStreamReader isr = new InputStreamReader(is);

   //get the XMLWorkerHelper Instance
   XMLWorkerHelper worker = XMLWorkerHelper.getInstance();
   //convert to PDF
   worker.parseXHtml(pdfWriter, document, isr);

   //close the document
   document.close();
   //close the writer
   pdfWriter.close();

  } catch (Exception e) {
      e.printStackTrace();
  }

 }

Пожалуйста, предложите решение для показа изображения в формате PDF.

Спасибо заранее.

Деива

4b9b3361

Ответ 1

Я думаю, вы можете сделать это легко, используя сервлет для просмотра изображения. Как написать сервлет для этого здесь

Вот вам образец диспетчера. Просто отредактируйте необходимые места по мере необходимости

@Controller
public class ImageController extends DispatcherServlet {



    private static final int DEFAULT_BUFFER_SIZE = 10240; // 10KB.

    // Properties ---------------------------------------------------------------------------------

    private String imagePath;

   @RequestMapping(value="images/{imageId:.+}", method = RequestMethod.GET)
   public @ResponseBody void getImage(@PathVariable String imageId,HttpServletRequest request, HttpServletResponse response){
        String requestedImage = request.getPathInfo();
         this.imagePath ="image path in server here";

         if (requestedImage == null) {
             // Do your thing if the image is not supplied to the request URI.
             // Throw an exception, or send 404, or show default/warning image, or just ignore it.
             try {
                response.sendError(HttpServletResponse.SC_NOT_FOUND);
             }catch(IOException ioException){
                logger.error("error image path incorrect:{}", ioException);

            } // 404.
             return;
         }

         File image=null;
        try {
            image = new File(imagePath, URLDecoder.decode(imageId, "UTF-8"));
        } catch (UnsupportedEncodingException unsupportedEncodingException) {
            logger.error("error image can not decode:{}", unsupportedEncodingException);

        }

         // Check if file actually exists in filesystem.
         if (!image.exists()) {
             // Do your thing if the file appears to be non-existing.
             // Throw an exception, or send 404, or show default/warning image, or just ignore it.
             try {
                response.sendError(HttpServletResponse.SC_NOT_FOUND);
             }catch(IOException ioException){
                logger.error("error image does not exists:{}", ioException);

            } // 404.
             return;
         }

         // Get content type by filename.
         String contentType = "jpeg";
         contentType="image/"+contentType;

         // Init servlet response.
         response.reset();
         response.setBufferSize(DEFAULT_BUFFER_SIZE);
         response.setContentType(contentType);
         response.setHeader("Content-Length", String.valueOf(image.length()));
         response.setHeader("Content-Disposition", "inline; filename=\"" + image.getName() + "\"");

         // Prepare streams.
         BufferedInputStream input = null;
         BufferedOutputStream output = null;

         try {
             // Open streams.
             try {
                input = new BufferedInputStream(new FileInputStream(image), DEFAULT_BUFFER_SIZE);
            } catch (FileNotFoundException e) {

                logger.error("error creating file input stream to the image file :{}", e);


            }
             try {

                 output = new BufferedOutputStream(response.getOutputStream(), DEFAULT_BUFFER_SIZE);

            } catch (IOException e) {


                logger.error("error creating output stream to the http response :{}", e);

            }

             // Write file contents to response.
             byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
             int length;
             try {
                while ((length = input.read(buffer)) > 0) {
                     output.write(buffer, 0, length);
                 }
            } catch (IOException e) {

                logger.error("error writing the image file to outputstream :{}", e);

            }
         } finally {
             // Gently close streams.
             close(output);
             close(input);
         }
     }

     // Helpers (can be refactored to public utility class) ----------------------------------------




private  void close(Closeable resource) {
    if (resource != null) {
        try {
            resource.close();
        } catch (IOException e) {
            // Do your thing with the exception. Print it, log it or mail it.
            logger.error("error closing resources:{}", e);
        }
    }
}




}

Ответ 2

чтобы показать изображение с помощью Itext, вам нужно изменить настройку по умолчанию для поставщика изображений. я делаю это из http://demo.itextsupport.com/xmlworker/itextdoc/flatsite.html

public class HtmlToPDF1 {
  public static void main(String ... args ) throws DocumentException, IOException {    

      FontFactory.registerDirectories();
      Document document = new Document();
      PdfWriter writer = PdfWriter.getInstance(document,
          new FileOutputStream("src/test/ressources/mypdf.pdf"));
      document.open(); HtmlPipelineContext htmlContext = new HtmlPipelineContext(null);
      htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
      htmlContext.setImageProvider(new AbstractImageProvider() {
          public String getImageRootPath() {
              return "/home/fallphenix/workspace/JAVA/JEE/testHTMLtoPDF/src/test/ressources/";
          }
      }); CSSResolver cssResolver =
            XMLWorkerHelper.getInstance().getDefaultCssResolver(true);
        Pipeline<?> pipeline =
            new CssResolverPipeline(cssResolver,
                    new HtmlPipeline(htmlContext,
                        new PdfWriterPipeline(document, writer)));
        XMLWorker worker = new XMLWorker(pipeline, true);
        XMLParser p = new XMLParser(worker);
        p.parse(new FileInputStream("src/test/ressources/other.html"));
        document.close();
          System.out.println("Done.");        
    }}

Ответ 3

Вот несколько примеров: https://developers.itextpdf.com/examples/xml-worker-itext5/html-images

htmlContext.setImageProvider(new AbstractImageProvider() {
    public String getImageRootPath() { return "src/main/resources/html/"; }
}); 

Если обрабатываемый HTML файл хранится в каталоге, который отличается от рабочего каталога, iText не сможет создавать объекты изображения. Мы должны предоставить реализацию интерфейса ImageProvider, который сообщает iText, что делать, если встречается тег img. Этот интерфейс имеет следующие методы:

Image retrieve(final String src);
String getImageRootPath();
void store(String src, Image img);
void reset();

Вы можете написать свой собственный класс, реализующий эти четыре метода, или вы можете подклассифицировать AbstractImageProvider. Предпочтительно использовать последний. XML Worker будет использовать метод store() класса AbstractImageProvider для кэширования всех объектов Image, которые встречаются на карте. Эти объекты будут повторно использоваться, когда метод retrieve() вызывается для изображения с тем же src. Если вы не кэшируете изображения, ваш PDF будет раздутым. Один и тот же бит и байты изображения будут записываться в PDF более одного раза. Метод reset() очищает кеш; он используется при клонировании ImageProvider. Наконец, метод getImageRootPath() не реализован.

Если обрабатываемый HTML файл хранится в каталоге, который отличается от рабочего каталога, iText не сможет создавать объекты изображения. Мы должны предоставить реализацию интерфейса ImageProvider, который сообщает iText, что делать, если встречается тег img. Этот интерфейс имеет следующие методы:

Вы можете написать свой собственный класс, реализующий эти четыре метода, или вы можете подклассифицировать AbstractImageProvider. Предпочтительно использовать последний. XML Worker будет использовать метод store() класса AbstractImageProvider для кэширования всех объектов Image, которые встречаются на карте. Эти объекты будут повторно использоваться, когда метод retrieve() вызывается для изображения с тем же src. Если вы не кэшируете изображения, ваш PDF будет раздутым. Один и тот же бит и байты изображения будут записываться в PDF более одного раза. Метод reset() очищает кеш; он используется при клонировании ImageProvider. Наконец, метод getImageRootPath() не реализован. Вы должны реализовать его самостоятельно, как это делается в следующем фрагменте:

Ответ 4

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

исследовать перегрузки iTextSharp.text.Image

EDIT:

Хотя код находится на С#, он может вам помочь.

Получите изображение с вашего локального диска как:

Bitmap image1;
image1 = new Bitmap(@"C:\Documents and Settings\All Users\" 
            + @"Documents\My Music\music.jpeg", true);

Примечание.. Если у вас есть изображение в папке вашего приложения, у нас есть функции, чтобы получить их путь к локальному файлу на С#. Не знаю о Java. Изображения с внешнего сайта можно загрузить как

System.Net.WebClient client = new WebClient();
client.DownloadFile(imageURL, localPathname);   // look into java to get local path

Теперь преобразуйте этот поток байтов в объект изображения как

MemoryStream imgMemoryStream = new MemoryStream(imgByteArray);
Image myImage = Drawing.Image.FromStream(imgMemoryStream);

Теперь создайте объект изображения iTextSharp из него и добавьте его в ваше приложение в качестве

iTextSharp.text.Image pic = iTextSharp.text.Image.GetInstance(myImage, System.Drawing.Imaging.ImageFormat.Jpeg);
document.Add(pic);

Надеюсь, это поможет вам.

Ответ 5

Я также столкнулся с той же проблемой.

но он работал с абсолютным путем изображения. кажется, не работает с удаленным путем. Какой идентификатор сделал это, сохраните изображение в временном расположении файловой системы и создайте pdf, наконец, удалите файл изображения из временного местоположения.

<img src="/home/jboss/temp/imgs/img.png"/>