gpt4 book ai didi

html - 使用iText从html内容到pdf的阿拉伯字符

转载 作者:行者123 更新时间:2023-11-28 04:52:09 31 4
gpt4 key购买 nike

在PDF生成中,我很难将HTML内容中的阿拉伯字符显示为“?”
我可以从字符串变量中显示阿拉伯文本。同时,我无法从HTML字符串生成阿拉伯文本。
我想用两列显示PDF,左边是英文,右边是阿拉伯文。
当我使用下面的程序转换成pdf时。请在这方面帮助我。

try
{
Document document = new Document(PageSize.A4, 50, 50, 50, 50);
ByteArrayOutputStream out = new ByteArrayOutputStream();
PdfWriter writer = PdfWriter.getInstance(document, out);
BaseFont bf = BaseFont.createFont("C:\\arial.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
Font font = new Font(bf, 8);
document.open();

BufferedReader br = new BufferedReader(new FileReader("C:\\style.css"));
StringBuffer fileContents = new StringBuffer();
String line = br.readLine();
while (line != null)
{
fileContents.append(line);
line = br.readLine();
}
br.close();
String styles = fileContents.toString(); //"p { font-family: Arial;}";

Paragraph cirNoEn = null;
Paragraph cirNoAr = null;

String htmlContentEn = null;
String htmlContentAr = null;

PdfPCell contentEnCell = new PdfPCell();
PdfPCell contentArCell = new PdfPCell();

cirNoEn = new Paragraph("Circular No. (" + cirEnNo + ")", new Font(bf, 14, Font.BOLD | Font.UNDERLINE));
cirNoAr = new Paragraph("رقم التعميم (" + cirArNo + ")", new Font(bf, 14, Font.BOLD | Font.UNDERLINE));

htmlContentEn = “< p >< span > Dear….</ span ></ p >”;
htmlContentAr = “< p >< span > رقم التعميم رقم التعميم </ p >< p > رقم التعميم ….</ span ></ p >”;
for (Element e : XMLWorkerHelper.parseToElementList(htmlContentEn, styles))
{
for (Chunk c : e.getChunks())
{
c.setFont(new Font(bf));
}
contentEnCell.addElement(e);
}
for (Element e : XMLWorkerHelper.parseToElementList(htmlContentAr, styles))
{
for (Chunk c:e.getChunks())
{
c.setFont(new Font(bf));
}
contentArCell.addElement(e);
}

PdfPCell emptyCell = new PdfPCell();
PdfPCell cirNoEnCell = new PdfPCell(cirNoEn);
PdfPCell cirNoArCell = new PdfPCell(cirNoAr);

cirNoEnCell.setHorizontalAlignment(Element.ALIGN_CENTER);
cirNoArCell.setHorizontalAlignment(Element.ALIGN_CENTER);

emptyCell.setBorder(Rectangle.NO_BORDER);
emptyCell.setFixedHeight(15);

cirNoEnCell.setBorder(Rectangle.NO_BORDER);
cirNoArCell.setBorder(Rectangle.NO_BORDER);
contentEnCell.setBorder(Rectangle.NO_BORDER);
contentArCell.setBorder(Rectangle.NO_BORDER);

cirNoArCell.setRunDirection(PdfWriter.RUN_DIRECTION_RTL);
contentArCell.setRunDirection(PdfWriter.RUN_DIRECTION_RTL);

contentEnCell.setNoWrap(false);
contentArCell.setNoWrap(false);

PdfPTable circularInfoTable = null;

emptyCell.setColspan(2);
circularInfoTable = new PdfPTable(2);
circularInfoTable.addCell(cirNoEnCell);
circularInfoTable.addCell(cirNoArCell);
circularInfoTable.addCell(emptyCell);
circularInfoTable.addCell(emptyCell);
circularInfoTable.addCell(emptyCell);
circularInfoTable.addCell(contentEnCell);
circularInfoTable.addCell(contentArCell);
circularInfoTable.addCell(emptyCell);

circularInfoTable.getDefaultCell().setBorder(PdfPCell.NO_BORDER);
circularInfoTable.setWidthPercentage(100);
document.add(circularInfoTable);

document.close();

}
catch (Exception e)
{

}

最佳答案

请看一下ParseHtml7ParseHtml8示例。他们接受带有阿拉伯字符的HTML输入,并使用相同的阿拉伯文本创建PDF:
在我们看代码之前,请允许我解释一下,在源代码中使用非ASCII字符不是一个好主意。例如:未完成:

 htmlContentAr = “<p><span> رقم التعميم رقم التعميم</p><p>رقم التعميم ….</span></p>”;

您永远不知道如何存储包含这些标志符号的Java文件。如果不是以UTF-8的形式存储,字符可能会看起来完全不同。众所周知,版本控制系统存在非ASCII字符的问题,甚至编译器也可能会出错。如果您真的想在代码中存储硬编码的 String值,请使用UNICODE表示法。部分问题是编码问题,您可以在此处阅读更多有关此问题的信息: Can't get Czech characters while generating a PDF
对于屏幕截图中显示的示例,我使用UTF-8编码保存了以下文件:
这就是文件中的内容:
<html>
<body style="font-family: Noto Naskh Arabic">
<p>رقم التعميم رقم التعميم</p>
<p>رقم التعميم</p>
</body>
</html>

这就是文件中的内容:
<html>
<body style="font-family: Noto Naskh Arabic">
<table>
<tr>
<td dir="rtl">رقم التعميم رقم التعميم</td>
<td dir="rtl">رقم التعميم</td>
</tr>
</table>
</body>
</html>

问题的第二部分涉及字体。使用一种知道如何绘制阿拉伯字形的字体是很重要的。很难相信 arabic.html就在 arabic2.html驱动器的根目录下。那不是个好主意。我希望您使用 arial.ttf这个词当然知道阿拉伯符号。
选择字体是不够的。您的HTML需要知道使用哪种字体系列。因为文档中的大多数示例使用的是Arial,所以我决定使用NOTO字体。我通过阅读这个问题发现了这些字体: iText pdf not displaying Chinese characters when using NOTO fonts or Source Hans。我真的很喜欢这些字体,因为它们很好,而且(几乎)每种语言都受支持。例如,我使用了 C:这意味着我需要定义这样的字体系列:
style="font-family: Noto Naskh Arabic"

我在XML的body标记中定义了样式,很明显,您可以选择定义它的位置:在外部CSS文件中,在 C:/windows/fonts/arialuni.ttf的style s部分,在 NotoNaskhArabic-Regular.ttf标记的级别,。。。这完全是你的选择,但你必须确定在什么地方使用哪种字体。
当然:当XML Worker遇到 <head>时,iText不知道在哪里可以找到对应的 <td>,除非我们注册了该字体。我们可以通过创建 font-family: Noto Naskh Arabic接口的实例来实现这一点。我选择使用 NotoNaskhArabic-Regular.ttf,但您可以自由编写自己的 FontProvider实现:
XMLWorkerFontProvider fontProvider = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
fontProvider.register("resources/fonts/NotoNaskhArabic-Regular.ttf");

还有一个障碍要克服:阿拉伯语是从右向左写的。我看到您想要在 XMLWorkerFontProvider级别定义运行方向,并使用 FontProvider将HTML内容添加到此单元格。这就是为什么我第一次写了一个类似的例子,名为 ParseHtml7
public void createPdf(String file) throws IOException, DocumentException {
// step 1
Document document = new Document();
// step 2
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(file));
// step 3
document.open();
// step 4
// Styles
CSSResolver cssResolver = new StyleAttrCSSResolver();
XMLWorkerFontProvider fontProvider = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
fontProvider.register("resources/fonts/NotoNaskhArabic-Regular.ttf");
CssAppliers cssAppliers = new CssAppliersImpl(fontProvider);
// HTML
HtmlPipelineContext htmlContext = new HtmlPipelineContext(cssAppliers);
htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
// Pipelines
ElementList elements = new ElementList();
ElementHandlerPipeline pdf = new ElementHandlerPipeline(elements, null);
HtmlPipeline html = new HtmlPipeline(htmlContext, pdf);
CssResolverPipeline css = new CssResolverPipeline(cssResolver, html);

// XML Worker
XMLWorker worker = new XMLWorker(css, true);
XMLParser p = new XMLParser(worker);
p.parse(new FileInputStream(HTML), Charset.forName("UTF-8"));

PdfPTable table = new PdfPTable(1);
PdfPCell cell = new PdfPCell();
cell.setRunDirection(PdfWriter.RUN_DIRECTION_RTL);
for (Element e : elements) {
cell.addElement(e);
}
table.addCell(cell);
document.add(table);
// step 5
document.close();
}

HTML中没有表,但是我们创建自己的 PdfPCell,使用run direction LTR将HTML中的内容添加到 ElementList,并将此单元格添加到表中,将表添加到文档中。
也许这是你的实际要求,但你为什么要这么复杂地做呢?如果您需要一个表,为什么不用HTML创建该表并定义一些RTL格式的单元格,如下所示:
<td dir="rtl">...</td>

这样,您就不必创建 PdfPTable,只需将HTML解析为PDF,就像 ParseHtml8示例中所做的那样:
public void createPdf(String file) throws IOException, DocumentException {
// step 1
Document document = new Document();
// step 2
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(file));
// step 3
document.open();
// step 4
// Styles
CSSResolver cssResolver = new StyleAttrCSSResolver();
XMLWorkerFontProvider fontProvider = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
fontProvider.register("resources/fonts/NotoNaskhArabic-Regular.ttf");
CssAppliers cssAppliers = new CssAppliersImpl(fontProvider);
HtmlPipelineContext htmlContext = new HtmlPipelineContext(cssAppliers);
htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());

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

// XML Worker
XMLWorker worker = new XMLWorker(css, true);
XMLParser p = new XMLParser(worker);
p.parse(new FileInputStream(HTML), Charset.forName("UTF-8"));;
// step 5
document.close();
}

本例中所需的代码更少,当您想要更改布局时,更改HTML就足够了。您不需要更改Java代码。
再举一个例子:在 ParseHtml9中,我创建了一个表,其中一列有英文名(“Lawrence of Arabia”),另一列有阿拉伯文翻译名(“لوانسلعبب”)。因为我需要英语和阿拉伯语的不同字体,所以我在 PdfPCell级别定义字体:
<table>
<tr>
<td>Lawrence of Arabia</td>
<td dir="rtl" style="font-family: Noto Naskh Arabic">لورانس العرب</td>
</tr>
</table>

第一列使用默认字体,从左到右不需要特殊设置。对于第二列,我定义了一个阿拉伯语字体,并将run direction设置为 ElementList
结果如下:
这比你在代码中要做的要容易得多。

关于html - 使用iText从html内容到pdf的阿拉伯字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30214147/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com