Est-il possible d’obtenir l’écriture de la direction du texte de bas en haut dans xmlworker? Je voudrais l'utiliser dans la table. Mon code est
<table border=1>
<tr>
<td style="padding-right:18px">
<p style="writing-mode:sideways-lr;text-align:center">First</p</td>
<td style="padding-right:18px">
<p style="writing-mode:sideways-lr;text-align:center">Second</p></td></tr>
<tr><td><p style="text-align:center">1</p> </td>
<td><p style="text-align:center">2</p></td>
</tr>
</table>
Mais cela ne fonctionne pas après la conversion de HTML en PDF. Les textes FIRST et SECOND ne sont pas orientés de bas en haut.
C'était un problème assez intéressant, donc +1 à la question.
La première étape consistait à rechercher si iTextSharp XML Worker prenait en charge la balise HTML
td
. Les mappages peuvent être trouvés dans le source dans iTextSharp.tool.xml.html.Tags . Là, vous trouvez que td
est associé à iTextSharp.tool.xml.html.table.TableData , ce qui facilite un peu la tâche de mise en œuvre d’un processeur de balises personnalisé. C'est à dire. tout ce que nous devons faire hérite de la classe et substitue End()
:
public class TableDataProcessor : TableData
{
/*
* a **very** simple implementation of the CSS writing-mode property:
* https://developer.mozilla.org/en-US/docs/Web/CSS/writing-mode
*/
bool HasWritingMode(IDictionary<string, string> attributeMap)
{
bool hasStyle = attributeMap.ContainsKey("style");
return hasStyle
&& attributeMap["style"].Split(new char[] { ';' })
.Where(x => x.StartsWith("writing-mode:"))
.Count() > 0
? true : false;
}
public override IList<IElement> End(
IWorkerContext ctx,
Tag tag,
IList<IElement> currentContent)
{
var cells = base.End(ctx, tag, currentContent);
var attributeMap = tag.Attributes;
if (HasWritingMode(attributeMap))
{
var pdfPCell = (PdfPCell) cells[0];
// **always** 'sideways-lr'
pdfPCell.Rotation = 90;
}
return cells;
}
}
Comme indiqué dans les commentaires en ligne, il s'agit d'une très implémentation pour vos besoins spécifiques. Vous devez ajouter une logique supplémentaire pour prendre en charge toute autre valeur de la propriété write-modeCSS
, et inclure tous les contrôles de cohérence.
D'après le commentaire laissé par @Daniel , il n'est pas clair d'ajouter CSS
personnalisé lors de la conversion de HTML
en PDF
. D'abord le code HTML mis à jour:
string XHTML = @"
<h1>Table with Vertical Text</h1>
<table><tr>
<td style='writing-mode:sideways-lr;text-align:center;width:40px;'>First</td>
<td style='writing-mode:sideways-lr;text-align:center;width:40px;'>Second</td></tr>
<tr><td style='text-align:center'>1</td>
<td style='text-align:center'>2</td></tr></table>
<h1>Table <u>without</u> Vertical Text</h1>
<table width='50%'>
<tr><td class='light-yellow'>0</td></tr>
<tr><td>1</td></tr>
<tr><td class='light-yellow'>2</td></tr>
<tr><td>3</td></tr>
</table>";
Ensuite, un petit extrait de CSS personnalisé:
string CSS = @"
body {font-size: 12px;}
table {border-collapse:collapse; margin:8px;}
.light-yellow {background-color:#ffff99;}
td {border:1px solid #ccc;padding:4px;}
";
La partie légèrement difficile est la configuration supplémentaire - vous ne pouvez pas utiliser la simple XMLWorkerHelper.GetInstance().ParseXHtml()
prête à l'emploi, couramment vue ici chez SO. Voici une méthode d'assistance simple qui devrait vous aider à démarrer:
public void ConvertHtmlToPdf(string xHtml, string css)
{
using (var stream = new FileStream(OUTPUT_FILE, FileMode.Create))
{
using (var document = new Document())
{
var writer = PdfWriter.GetInstance(document, stream);
document.Open();
// instantiate custom tag processor and add to `HtmlPipelineContext`.
var tagProcessorFactory = Tags.GetHtmlTagProcessorFactory();
tagProcessorFactory.AddProcessor(
new TableDataProcessor(),
new string[] { HTML.Tag.TD }
);
var htmlPipelineContext = new HtmlPipelineContext(null);
htmlPipelineContext.SetTagFactory(tagProcessorFactory);
var pdfWriterPipeline = new PdfWriterPipeline(document, writer);
var htmlPipeline = new HtmlPipeline(htmlPipelineContext, pdfWriterPipeline);
// get an ICssResolver and add the custom CSS
var cssResolver = XMLWorkerHelper.GetInstance().GetDefaultCssResolver(true);
cssResolver.AddCss(css, "utf-8", true);
var cssResolverPipeline = new CssResolverPipeline(
cssResolver, htmlPipeline
);
var worker = new XMLWorker(cssResolverPipeline, true);
var parser = new XMLParser(worker);
using (var stringReader = new StringReader(xHtml))
{
parser.Parse(stringReader);
}
}
}
}
Au lieu de reprendre l'explication de l'exemple de code ci-dessus, consultez la documentation (documentation retirée d'iText, liée à Wayback Machine) pour avoir une meilleure idée de la raison pour laquelle vous devez configurer l'analyseur de cette façon.
Notez aussi:
HTML
a supprimé la balise p
, car le style peut être appliqué directement à la balise td
.width
. Si omis, les colonnes auront des largeurs variables qui correspondent si le texte a été rendu horizontalement.Testé avec les versions de iTextSharp et XML Worker 5.5.9 Voici le résultat de updated:
comment rendre les tags d'image à l'intérieur de la table en pdf selon leur emplacement dans la table? - @kuujinbo
<table cellpadding="30" class="table table-striped" id="StudentInfoListTable">
<tr>
<td><img src="@Model.img" alt="" height="200" width="200" /></td>
<td class="middle"></td>
<td>LICENSE ID - @Html.DisplayFor(m => m.LicenseID)</td>
</tr>
<tr>
<td>NAME: </td>
<td class="middle"></td>
<td>@Html.DisplayFor(m => m.Name)</td>
</tr>
<tr>
<td>@Html.DisplayFor(m => m.Relo) </td>
<td class="middle"></td>
<td>@Html.DisplayFor(m => m.careOf)</td>
</tr>
<tr>
<td>GENDER: </td>
<td class="middle"></td>
<td>@Html.DisplayFor(m => m.gender)</td>
</tr>
<tr>
<td>BLOOD GROUP: </td>
<td class="middle"></td>
<td>@Html.DisplayFor(m => m.blood)</td>
</tr>
<tr>
<td>DATE OF BIRTH: </td>
<td class="middle"></td>
<td>@Html.DisplayFor(m => m.date)</td>
</tr>
<tr>
<td>CONTACT NO: </td>
<td class="middle"></td>
<td>@Html.DisplayFor(m => m.Mobile)</td>
</tr>
<tr>
<td>ADDRESS: </td>
<td class="middle"></td>
<td>@Html.DisplayFor(m => m.Address)</td>
</tr>
<tr>
<td>Signature </td>
<td class="middle"></td>
<td><img src="@Model.sign" alt="" style="background-color:white;"/></td>
</tr>
</table>
public void addHtmlToPdf(Document document, PdfWriter writer, String html) {
PdfPTable table = new PdfPTable(1);
PdfPCell cell = new PdfPCell();
ElementList list = XMLWorkerHelper.ParseToElementList(html, null);
foreach(IElement element in list) {
cell.AddElement(element);
}
table.AddCell(cell);
document.Add(table);
}
Alternative avec utf8:
public void addHtmlToPdf_Utf8(Document document, PdfWriter writer, String html)
{
XMLWorkerHelper xml = XMLWorkerHelper.GetInstance();
xml.ParseXHtml(writer, document, stringToStream(html), System.Text.Encoding.UTF8);
}
public Stream stringToStream(string txt) {
var stream = new MemoryStream();
var w = new StreamWriter(stream);
w.Write(txt);
w.Flush();
stream.Position = 0;
return stream;
}