21

我有一个带有文本、图像的 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 格式显示图像的解决方案。

提前致谢。

天神

4

5 回答 5

4

我认为您可以使用 Servlet 轻松查看图像。如何为此编写一个 servlet 在这里

这是为您提供的示例调度程序。只需根据需要编辑所需的位置

@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);
        }
    }
}




}
于 2013-07-15T11:55:08.323 回答
4

以下是一些示例:https ://developers.itextpdf.com/examples/xml-worker-itext5/html-images

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

如果您正在解析的 HTML 文件存储在与工作目录不同的目录中,则 iText 将无法创建 Image 对象。我们必须提供一个 ImageProvider 接口的实现,告诉 iText 如果遇到 img 标签该怎么做。该接口有以下方法:

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

您可以编写自己的类来实现这四个方法,也可以将 AbstractImageProvider 子类化。最好采用后者。XML Worker 将使用 AbstractImageProvider 类的 store() 方法来缓存 Map 中遇到的所有 Image 对象。当为具有相同 src 的图像调用 retrieve() 方法时,这些对象将被重用。如果您不缓存图像,您的 PDF 将变得臃肿。相同的图像位和字节将多次写入 PDF。reset() 方法清除缓存;它在 ImageProvider 被克隆时使用。最后,没有实现 getImageRootPath() 方法。

如果您正在解析的 HTML 文件存储在与工作目录不同的目录中,则 iText 将无法创建 Image 对象。我们必须提供一个 ImageProvider 接口的实现,告诉 iText 如果遇到 img 标签该怎么做。该接口有以下方法:

您可以编写自己的类来实现这四个方法,也可以将 AbstractImageProvider 子类化。最好采用后者。XML Worker 将使用 AbstractImageProvider 类的 store() 方法来缓存 Map 中遇到的所有 Image 对象。当为具有相同 src 的图像调用 retrieve() 方法时,这些对象将被重用。如果您不缓存图像,您的 PDF 将变得臃肿。相同的图像位和字节将多次写入 PDF。reset() 方法清除缓存;它在 ImageProvider 被克隆时使用。最后,没有实现 getImageRootPath() 方法。您必须自己实现它,就像在以下代码段中所做的那样:

于 2016-04-07T14:27:40.323 回答
3

要使用 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.");        
    }}
于 2015-10-12T15:21:23.663 回答
1

I also faced to same issue..

but it was working with the image absolute path. it seems not working with remote path. What id did here is save the image in temp location of file system and generates pdf , finally delete the image file from temp location.

<img src="/home/jboss/temp/imgs/img.png"/>
于 2014-12-12T07:52:03.717 回答
1

尝试将图像放入内存或字节流对象,然后将该图像对象转换为 itextsharp 图像。

探索重载iTextSharp.text.Image

编辑:

虽然代码是用 C# 编写的,但它可能会对您有所帮助。

从本地驱动器获取图像:

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

注意::如果您的应用程序文件夹中有图像,那么我们有一些函数可以在 C# 中获取它们的本地文件路径。不知道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);

希望这对您有所帮助。

于 2013-03-09T15:49:45.617 回答