2016-11-25 7 views
8

Я использую библиотеку Itext для android для преобразования html в pdf, который отлично работает, но при определенных вещах он не разбирается правильно. Я хочу создать разделитель пунктирной линии красного цвета, но он всегда дает мне сплошной разделитель строк с темно-серым цветом.Встроенный CSS для hr не применяется при преобразовании html в pdf с использованием библиотеки iText

Мой HTML тег

<hr noshade style="border: 0; width:100%;border-bottom-width: 1px; border-bottom-style: dotted; border-bottom-color: red"> 

Мой код преобразования

 Document document = new Document(PageSize.A4); 

     //this sets the margin to the created pdf 
     document.setMargins(35, 35, 150, 100); 

     PdfWriter writer = PdfWriter.getInstance(document, 
       new FileOutputStream(fileWithinMyDir)); 
     if (isPrescription) { 
      HeaderFooterPageEvent event = new HeaderFooterPageEvent(); 
      writer.setPageEvent(event); 
     } else { 
      CertificateFooterPageEvent event = new CertificateFooterPageEvent(); 
      writer.setPageEvent(event); 
     } 
     document.open(); 
     HtmlPipelineContext htmlContext = new HtmlPipelineContext(null); 
     htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory()); 
     htmlContext.setImageProvider(new AbstractImageProvider() { 
      public String getImageRootPath() { 

       Uri uri = Uri.parse("file:///android_asset/"); 

       return uri.toString(); 
      } 
     }); 


     CSSResolver cssResolver = 
       XMLWorkerHelper.getInstance().getDefaultCssResolver(false); 

     // Pipelines 
     PdfWriterPipeline pdf = new PdfWriterPipeline(document, writer); 
     HtmlPipeline html = new HtmlPipeline(htmlContext, pdf); 
     CssResolverPipeline css = new CssResolverPipeline(cssResolver, html); 

     XMLWorker worker = new XMLWorker(css, true); 

     XMLParser p = new XMLParser(worker); 
     InputStream is = new ByteArrayInputStream(htmlString.getBytes()); 
     XMLWorkerHelper.getInstance().parseXHtml(writer, document, is); 
     p.parse(is); 

     document.close(); 
+0

Не используется iText, поэтому я могу предложить только предложение.Попробуйте добавить 'background-color: transparent;' в стили 'hr' и удалить 'noshade':'


+0

@HiddenHobbes все тот же, проблема с библиотекой, и я ищу работу. –

ответ

4

Я разработчик .NET, так что код находится в C#. Но вы должны иметь возможность легко перевести следующее.

iText - это библиотека в формате PDF, а обработка [X]HTML довольно сложна, поэтому она не является полнофункциональной в этом отношении. Всякий раз, когда разбор [X]HTML и дела идут не так, как вы ожидаете для конкретных тегов, основные шаги, которые вы должны следовать, являются:

  1. Проверьте XML Worker поддерживает тег: Tags class.
  2. Если тег поддерживается, в этом случае это правда, посмотрите на реализацию по умолчанию. Здесь он обрабатывается the HorizontalRule class. Тем не менее, мы видим, что нет поддержки для вашего случая использования, поэтому один из способов - использовать этот код в качестве плана. (см. ниже). Вы также можете наследовать от определенного класса тега и переопределить метод End() as done here. В любом случае, все, что вы делаете, это внедрение специального процессора тегов.
  3. Если тег не поддерживается, вам необходимо свернуть свой собственный тег-процессор, наследуя от AbstractTagProcessor.

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

public class CustomHorizontalRule : AbstractTagProcessor 
{ 
    public override IList<IElement> Start(IWorkerContext ctx, Tag tag) 
    { 
     IList<IElement> result; 
     LineSeparator lineSeparator; 
     var cssUtil = CssUtils.GetInstance(); 

     try 
     { 
      IList<IElement> list = new List<IElement>(); 
      HtmlPipelineContext htmlPipelineContext = this.GetHtmlPipelineContext(ctx); 

      Paragraph paragraph = new Paragraph(); 
      IDictionary<string, string> css = tag.CSS; 
      float baseValue = 12f; 
      if (css.ContainsKey("font-size")) 
      { 
       baseValue = cssUtil.ParsePxInCmMmPcToPt(css["font-size"]); 
      } 
      string text; 
      css.TryGetValue("margin-top", out text); 
      if (text == null) text = "0.5em"; 

      string text2; 
      css.TryGetValue("margin-bottom", out text2); 
      if (text2 == null) text2 = "0.5em"; 

      string border; 
      css.TryGetValue(CSS.Property.BORDER_BOTTOM_STYLE, out border); 
      lineSeparator = border != null && border == "dotted" 
       ? new DottedLineSeparator() 
       : new LineSeparator(); 

      var element = (LineSeparator)this.GetCssAppliers().Apply(
       lineSeparator, tag, htmlPipelineContext 
      ); 

      string color; 
      css.TryGetValue(CSS.Property.BORDER_BOTTOM_COLOR, out color); 
      if (color != null) 
      { 
       // WebColors deprecated, but docs don't state replacement 
       element.LineColor = WebColors.GetRGBColor(color); 
      } 

      paragraph.SpacingBefore += cssUtil.ParseValueToPt(text, baseValue); 
      paragraph.SpacingAfter += cssUtil.ParseValueToPt(text2, baseValue); 
      paragraph.Leading = 0f; 
      paragraph.Add(element); 
      list.Add(paragraph); 
      result = list; 
     } 
     catch (NoCustomContextException cause) 
     { 
      throw new RuntimeWorkerException(
       LocaleMessages.GetInstance().GetMessage("customcontext.404"), 
       cause 
      ); 
     } 
     return result; 
    } 
} 

Большая часть кода берется непосредственно из существующего источника, за исключением проверок для CSS.Property.BORDER_BOTTOM_STYLE и CSS.Property.BORDER_BOTTOM_COLOR установить стиль границы и цвет, если они встраиваются в <hr>style атрибут.

Затем добавьте процессор пользовательских тегов выше в XML Рабочий TagProcessorFactory:

using (var stream = new FileStream(OUTPUT_FILE, FileMode.Create)) 
{ 
    using (var document = new Document()) 
    { 
     var writer = PdfWriter.GetInstance(document, stream); 
     document.Open(); 

     var tagProcessorFactory = Tags.GetHtmlTagProcessorFactory(); 
     // custom tag processor above 
     tagProcessorFactory.AddProcessor(
      new CustomHorizontalRule(), 
      new string[] { HTML.Tag.HR } 
     ); 
     var htmlPipelineContext = new HtmlPipelineContext(null); 
     htmlPipelineContext.SetTagFactory(tagProcessorFactory); 

     var pdfWriterPipeline = new PdfWriterPipeline(document, writer); 
     var htmlPipeline = new HtmlPipeline(htmlPipelineContext, pdfWriterPipeline); 
     var cssResolver = XMLWorkerHelper.GetInstance().GetDefaultCssResolver(true); 
     var cssResolverPipeline = new CssResolverPipeline(
      cssResolver, htmlPipeline 
     ); 

     var worker = new XMLWorker(cssResolverPipeline, true); 
     var parser = new XMLParser(worker); 
     var xHtml = "<hr style='border:1px dotted red' />"; 
     using (var stringReader = new StringReader(xHtml)) 
     { 
      parser.Parse(stringReader); 
     } 
    } 
} 

Одна вещь, чтобы отметить, что несмотря на то, что мы используем встроенный стиль сокращенная border, CSS парсер IText, как представляется, установить все стили внутри. I.e., вы можете использовать любой из четырех стилей ручной работы для проверки - я просто использовал CSS.Property.BORDER_BOTTOM_STYLE и CSS.Property.BORDER_BOTTOM_COLOR.

В результате PDF:

enter image description here

0

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

Смежные вопросы