iTextSharp 5 caractère polonais

J’ai un problème avec le caractère polonais en utilisant itextSharp. Je veux créer un fichier pdf à partir de HTML. Tout fonctionne bien, mais manque de caractère polonais. J’utilise la fonction inférieure:

private void createPDF(ssortingng html) { //MemoryStream msOutput = new MemoryStream(); TextReader reader = new SsortingngReader(html);// step 1: creation of a document-object Document document = new Document(PageSize.A4, 30, 30, 30, 30); // step 2: // we create a writer that listens to the document // and directs a XML-stream to a file PdfWriter writer = PdfWriter.GetInstance(document, new FileStream("Test.pdf", FileMode.Create)); // step 3: we create a worker parse the document HTMLWorker worker = new HTMLWorker(document); // step 4: we open document and start the worker on the document document.Open(); worker.StartDocument(); // step 5: parse the html into the document worker.Parse(reader); // step 6: close the document and the worker worker.EndDocument(); worker.Close(); document.Close(); } 

Et essayez de l’utiliser:

createPDF (“Ąąć곣ŃńóÓŚśŹźŻż”);

J’essaye de mettre:

BaseFont bf = BaseFont.CreateFont (BaseFont.TIMES_ROMAN, Encoding.UTF8.HeaderName, BaseFont.EMBEDDED);

  writer.DirectContent.SetFontAndSize(bf, 16); 

Mais ça ne marche pas

Avez-vous une idée??

Cordialement

Pour résumer ce que @Mark Storer a dit:

 private void createPDF(ssortingng html) { //MemoryStream msOutput = new MemoryStream(); TextReader reader = new SsortingngReader(html);// step 1: creation of a document-object Document document = new Document(PageSize.A4, 30, 30, 30, 30); // step 2: // we create a writer that listens to the document // and directs a XML-stream to a file PdfWriter writer = PdfWriter.GetInstance(document, new FileStream("Test.pdf", FileMode.Create)); // step 3: we create a worker parse the document HTMLWorker worker = new HTMLWorker(document); // step 4: we open document and start the worker on the document document.Open(); // step 4.1: register a unicode font and assign it an allias FontFactory.Register("C:\\Windows\\Fonts\\ARIALUNI.TTF", "arial unicode ms"); // step 4.2: create a style sheet and set the encoding to Identity-H iTextSharp.text.html.simpleparser.StyleSheet ST = New iTextSharp.text.html.simpleparser.StyleSheet(); ST.LoadTagStyle("body", "encoding", "Identity-H"); // step 4.3: assign the style sheet to the html parser worker.Style = ST; worker.StartDocument(); // step 5: parse the html into the document worker.Parse(reader); // step 6: close the document and the worker worker.EndDocument(); worker.Close(); document.Close(); } 

Et lorsque vous l’appelez, enveloppez votre texte dans une police de caractères en utilisant le nom que vous avez enregistré ci-dessus:

 createPDF("ĄąćęĘłŁŃńóÓŚśŹźŻż"); 

J’ai eu la réponse! =) (spécifiquement ciblé pour le vernis) Je me sens obligé de le mettre ici dans cet ancien fil de discussion, car je suis sûr de ne pas être le dernier à le trouver.

Je suis sérieusement déçu par le fait qu’il n’y a pas de bonne réponse à cette question … la plupart d’entre eux suggèrent d’utiliser le fichier ARIALUNI.TTF dans votre dossier Windows FONTS, ce qui augmente la taille de votre fichier PDF. La solution n’a pas besoin d’être si drastique …

Beaucoup d’autres suggèrent des exemples montrant un codage avec cp1252 qui échoue sur Arial et ne fonctionne pas avec Helvetica pour le texte polonais.

J’utilise iTextSharp 4.1.6 … l’astuce est … cp1257! Et vous pouvez l’utiliser avec BaseFont.Courier, BaseFont.Helvetica, BaseFont.Times-Roman

Cela fonctionne … et mes fichiers PDF sont minuscules (3kb!)

 document.Open(); var bigFont = FontFactory.GetFont(BaseFont.COURIER, BaseFont.CP1257, 18, Font.BOLD); var para = new Paragraph("Oryginał", bigFont); document.Add(pgDocType); document.Close(); 

Je testerai plus tard et m’assurerai de pouvoir les ouvrir et les lire sous Windows XP et Mac OSX en plus de Windows 7.

Lors de la création de votre BaseFont, vous devez spécifier que vous souhaitez utiliser des caractères UniCode. Cette réponse montre comment.

En parcourant divers forums et questions relatives à la superposition, je n’ai trouvé aucune réponse avec une solution complexe au problème des caractères spéciaux. J’ai essayé de fournir un en échange d’une réponse assez longue à la question. Espérons que cela aidera quelqu’un …

J’ai utilisé XMLWorker de SourceForge lorsque HtmlWorker est devenu obsolète. Le problème avec les caractères spéciaux est resté pensé. J’ai trouvé deux solutions qui fonctionnent réellement et peuvent être utilisées séparément et combinées.

Solution HTML et CSS

Chaque balise impliquée doit spécifier un style de famille de fonts afin d’être interprétée correctement par la méthode ParseXHtml (je ne sais pas pourquoi l’inheritance de styles de balises nestedes ne fonctionne pas ici, mais il semble que cela ne fonctionne pas vraiment ou pas complètement).

Cette solution permet de modifier les PDF résultants en fonction du code HTML uniquement. Ainsi, certains scénarios sans recompilation de code peuvent avoir lieu.

Le code simplifié (pour une application MVC) ressemblerait à ceci:

Manette:

 public FileStreamResult GetPdf() { const ssortingng CONTENT_TYPE = "application/pdf" var fileName = "mySimple.pdf"; var html = GetViewPageHtmlCode(); //the way how to capture view HTML are described in other threads, eg [here][2] var css = Server.MapPath("~/Content/Pdf.css"); using (var capturedActionStream = new MemoryStream(USED_ENCODING.GetBytes(html))) { using (var cssFile = new FileStream(css), FileMode.Open)) { var memoryStream = new MemoryStream(); //to create landscape, use PageSize.A4.Rotate() for pageSize var document = new Document(PageSize.A4, 30, 30, 10, 10); var writer = PdfWriter.GetInstance(document, memoryStream); var worker = XMLWorkerHelper.GetInstance(); document.Open(); worker.ParseXHtml(writer, document, capturedActionStream, cssFile); writer.CloseStream = false; document.Close(); memoryStream.Position = 0; //to enforce file download HttpContext.Response.AddHeader( "Content-Disposition", Ssortingng.Format("attachment; filename={0}", fileName)); var wrappedPdf = new FileStreamResult(memoryStream, CONTENT_TYPE); return wrappedPdf; } } } 

CSS:

 body { background-color: white; font-size: .85em; font-family: Arial; margin: 0; padding: 0; color: black; } p, ul { margin-bottom: 20px; line-height: 1.6em; } div, span { font-family: Arial; } h1, h2, h3, h4, h5, h6 { font-size: 1.5em; color: #000; font-family: Arial; } 

Disposition de la vue

     @ViewBag.Title    
@RenderBody()

Voir page

 @{ ViewBag.Title = "PDF page title" } 

@ViewBag.Title

ěščřžýáíéů ĚŠČŘŽÝÁÍÉŮ

Solution de remplacement de fonts de code interne

Dans cette solution, la police renvoyée par IFontProvider est modifiée en une représentation correcte des caractères spéciaux et le codage BaseFont.IDENTITY_H est utilisé. L’avantage de cette approche est qu’il n’ya qu’une police utilisée. C’est aussi un inconvénient de la sorte.

De plus, cette solution attend de la police qu’elle fasse partie du projet (fichier (s) * .ttf placé (s) dans le dossier Content/Fonts ).

Les fonts peuvent également être récupérées à partir de l’emplacement des fonts Windows: Environment.GetFolderPath(Environment.SpecialFolder.Fonts) – cela nécessite la connaissance (ou la conviction) des fonts installées sur le serveur ou le contrôle du serveur.

FontProvider (sur FontFactory )

J’ai pris la liberté d’étendre un peu la solution de Gregor S , qui fournit FontFactory plus complexe et qui peut être utilisé pour une variété de “modèles” HTML poussés via XMLWorker.

 public class CustomFontFactory : FontFactoryImp { public const Single DEFAULT_FONT_SIZE = 12; public const Int32 DEFAULT_FONT_STYLE = 0; public static readonly BaseColor DEFAULT_FONT_COLOR = BaseColor.BLACK; public Ssortingng DefaultFontPath { get; private set; } public Ssortingng DefaultFontEncoding { get; private set; } public Boolean DefaultFontEmbedding { get; private set; } public Single DefaultFontSize { get; private set; } public Int32 DefaultFontStyle { get; private set; } public BaseColor DefaultFontColor { get; private set; } public Boolean ReplaceEncodingWithDefault { get; set; } public Boolean ReplaceEmbeddingWithDefault { get; set; } public Boolean ReplaceFontWithDefault { get; set; } public Boolean ReplaceSizeWithDefault { get; set; } public Boolean ReplaceStyleWithDefault { get; set; } public Boolean ReplaceColorWithDefault { get; set; } public BaseFont DefaultBaseFont { get; protected set; } public CustomFontFactory( Ssortingng defaultFontFilePath, Ssortingng defaultFontEncoding = BaseFont.IDENTITY_H, Boolean defaultFontEmbedding = BaseFont.EMBEDDED, Single? defaultFontSize = null, Int32? defaultFontStyle = null, BaseColor defaultFontColor = null, Boolean automaticalySetReplacementForNullables = true) { //set default font properties DefaultFontPath = defaultFontFilePath; DefaultFontEncoding = defaultFontEncoding; DefaultFontEmbedding = defaultFontEmbedding; DefaultFontColor = defaultFontColor == null ? DEFAULT_FONT_COLOR : defaultFontColor; DefaultFontSize = defaultFontSize.HasValue ? defaultFontSize.Value : DEFAULT_FONT_SIZE; DefaultFontStyle = defaultFontStyle.HasValue ? defaultFontStyle.Value : DEFAULT_FONT_STYLE; //set default replacement options ReplaceFontWithDefault = false; ReplaceEncodingWithDefault = true; ReplaceEmbeddingWithDefault = false; if (automaticalySetReplacementForNullables) { ReplaceSizeWithDefault = defaultFontSize.HasValue; ReplaceStyleWithDefault = defaultFontStyle.HasValue; ReplaceColorWithDefault = defaultFontColor != null; } //define default font DefaultBaseFont = BaseFont.CreateFont(DefaultFontPath, DefaultFontEncoding, DefaultFontEmbedding); //register system fonts FontFactory.RegisterDirectories(); } protected Font GetBaseFont(Single size, Int32 style, BaseColor color) { var baseFont = new Font(DefaultBaseFont, size, style, color); return baseFont; } public override Font GetFont(Ssortingng fontname, Ssortingng encoding, Boolean embedded, Single size, Int32 style, BaseColor color, Boolean cached) { //eventually replace expected font properties size = ReplaceSizeWithDefault ? DefaultFontSize : size; style = ReplaceStyleWithDefault ? DefaultFontStyle : style; encoding = ReplaceEncodingWithDefault ? DefaultFontEncoding : encoding; embedded = ReplaceEmbeddingWithDefault ? DefaultFontEmbedding : embedded; //get font Font font = null; if (ReplaceFontWithDefault) { font = GetBaseFont( size, style, color); } else { font = FontFactory.GetFont( fontname, encoding, embedded, size, style, color, cached); if (font.BaseFont == null) font = GetBaseFont( size, style, color); } return font; } } 

Manette

 private const Ssortingng DEFAULT_FONT_LOCATION = "~/Content/Fonts"; private const Ssortingng DEFAULT_FONT_NAME = "arialn.ttf"; public FileStreamResult GetPdf() { const ssortingng CONTENT_TYPE = "application/pdf" var fileName = "mySimple.pdf"; var html = GetViewPageHtmlCode(); //the way how to capture view HTML are described in other threads, eg var css = Server.MapPath("~/Content/Pdf.css"); using (var capturedActionStream = new MemoryStream(USED_ENCODING.GetBytes(html))) { using (var cssFile = new FileStream(css), FileMode.Open)) { var memoryStream = new MemoryStream(); var document = new Document(PageSize.A4, 30, 30, 10, 10); //to create landscape, use PageSize.A4.Rotate() for pageSize var writer = PdfWriter.GetInstance(document, memoryStream); var worker = XMLWorkerHelper.GetInstance(); var defaultFontPath = Server .MapPath(Path .Combine( DEFAULT_FONT_LOCATION, DEFAULT_FONT_NAME)); var fontProvider = new CustomFontFactory(defaultFontPath); document.Open(); worker.ParseXHtml(writer, document, capturedActionStream, cssFile, fontProvider); writer.CloseStream = false; document.Close(); memoryStream.Position = 0; //to enforce file download HttpContext.Response.AddHeader( "Content-Disposition", Ssortingng.Format("attachment; filename={0}", fileName)); var wrappedPdf = new FileStreamResult(memoryStream, CONTENT_TYPE); return wrappedPdf; } } } 

CSS:

 body { background-color: white; font-size: .85em; font-family: "Trebuchet MS", Verdana, Helvetica, Sans-Serif; margin: 0; padding: 0; color: black; } p, ul { margin-bottom: 20px; line-height: 1.6em; } h1, h2, h3, h4, h5, h6 { font-size: 1.5em; color: #000; } 

Disposition de la vue

     @ViewBag.Title    
@RenderBody()

Voir page

 @{ ViewBag.Title = "PDF page title" } 

@ViewBag.Title

ěščřžýáíéů ĚŠČŘŽÝÁÍÉŮ

Autres sources (re) utiles:

  • Cause du problème
  • Travailler avec des fonts
  • Un tas de solutions alternatives et de remplacement de fonts
  • À propos des fournisseurs de fonts

1) iText 5.0.6 a été publié aujourd’hui avec une refonte majeure du code de conversion HTML-> PDF. Je vous suggère d’essayer le nouveau code à la place.

2) Je suis presque sûr que définir le directContent comme tel n’affectera pas le contenu pdf généré par HTMLWorker. Je suis sûr à 99% que la police sera [ré] configurée avant que le texte ne soit dessiné.

3) Essayez d’encapsuler votre chaîne dans les balises . Je doute sérieusement que la police par défaut choisie par HTMLWorker convienne à la tâche.

Nan. Helvetica avec WinAnsiEncoding est la valeur par défaut. Ne convient absolument pas aux langues autres que l’anglais, l’allemand, le français et l’espagnol.

Vous devriez pouvoir utiliser HTMLWorker.setStyleSheet pour définir des valeurs par défaut plus conviviales. Vous voudrez définir le “visage” et le “codage” sur quelque chose de plus convivial pour le polonais. Je recommande “Identity-H” pour l’encodage, qui donne access à tous les caractères de la police de caractères utilisée, quelle que soit la langue. Depuis une police, il existe un programme appelé “charmap.exe” depuis WayBack qui vous indiquera les caractères disponibles pour une police dans un codage donné (y compris unicode). La famille “Arial” a bonne mine, à l’instar de plusieurs autres.


“le nouveau code” ne changera probablement aucun comportement que vous observez. C’est une refactorisation pour faciliter les changements futurs (la prochaine version si je comprends bien).

Ma suggestion est d’aller avec setStyleSheet() :

  // step 3: we create a worker parse the document HTMLWorker worker = new HTMLWorker(document); StyleSheet sheet = new StyleSheet; HashMap styleMap = new HashMap(); styleMap.put("face", "Arial"); // default font styleMap.put("encoding", "Identity-H"); // default encoding Ssortingng tags[] = {"p", "div", ...}; for (Ssortingng tag : tags) { sheet.applyStyle( tag, styleMap ); } 

Je ne suis pas sûr, mais vous pourriez peut-être simplement applyStyle("body", styleMap) et le applyStyle("body", styleMap) cascade dans tout ce qu’il contient, mais je ne suis pas sûr. Je ne suis pas sûr non plus que cela adresse votre test 1-line car il n’y a pas de tags impliqués IIRC, nous construisons une balise body s’il n’y en a pas, mais je n’en suis pas du tout sûr.