编辑:更好的解释: 在为这个问题设定赏金之前,我想更清楚地说明我需要的东西:
我需要.NET库来生成可打印的文档。用户应该能够使用我的应用程序或使用外部工具(如Adobe Acrobat reader)打印他们看到的完全相同的文档。它不一定是用于生成PDF文档的库,任何满足上述条件的文档格式都可以。
我需要该库来支持以下场景:
情景1:
情景2:
请注意第二种情况:我的文字包含上标中的某些部分 - 例如AAA{v-superscript text}BBB
(其中{}
括号中的文字是上标)。图书馆需要能够使用正确的kerning打印此文本。如果没有正确的字距调整,则上一个A
和第一个上标v
之间的差距将与上一个上标t
和第一个B
之间的差距相同。对于用户来说,看起来A
和上标v
之间有一个空格,但在最后一个上标字母后面没有空格。所以文字看起来很难看。如果库要正确处理它,它将有方法立即打印整个文本AAA{v-superscript text}BBB
,并指定其中一部分是上标。然后它会在正常文本和上标之间使用正确的字距调整。
情景3:
图书馆应该是免费的而不是GPL(LGPL没问题)。有什么东西可以让我做我需要的东西吗?可以用iTextSharp(版本4.1.6即LGPL而不是AGPL)来完成吗?或者也许使用固定文档?感谢您的任何建议。
原始问题:
我需要为用户在.NET(C#)应用程序中排版复杂文档。这些文件的主要用途是用于印刷。
文档将包含文本和简单生成的图形。文本和图形的布局将是复杂的并且需要计算(换句话说,文档中的文本位置需要由我的代码控制,它不会由选择的库自动完成。)
以下是我的API要求:
它不一定是用于创建PDF文档的库 - 任何其他“您看到的将要打印的内容”文档格式也可以。如果有WPF组件可以显示这样的文档,这是一个优势。 我知道有iTextSharp但是用iTextSharp来实现要求并不容易。当然,满足上述要求的一些PDF生成库也是很好的解决方案。
感谢您提出任何建议,我也很乐意提供详细信息或更清晰的解释。
答案 0 :(得分:4)
您可以查看Docotic.Pdf Library(免责声明:我为Bit Miracle工作)。 它具有用户友好的API和一组良好的样本,您可以在线查看或在样本查看器应用程序中运行。
它也满足您的要求:
您可以使用PdfCanvas.MeasureText()方法。
有许多重载允许在任意位置或区域显示文本。
http://bitmiracle.com/pdf-library/help/pdfcanvas.drawstring.aspx
http://bitmiracle.com/pdf-library/help/pdfcanvas.drawtext.aspx
PdfCanvas.TextRise属性允许显示上标文本。您可以将它与PdfCanvas.FontSize属性结合使用,以控制上标文本的大小。 例子: http://bitmiracle.com/pdf-library/help/text-rise.aspx
如果您对上标文本使用不同的字体或字体大小,则直接调用PdfCanvas.MeasureText()方法将产生不正确的结果。
有解决方法:
- 分别测量用不同字体绘制的字符串的每个部分,然后对所有宽度求和。
- 如果你想获得绘制文本的宽度,你可以简单地从绘图后的最终文本位置中减去初始文本位置。
支持的。看样品:
http://bitmiracle.com/pdf-library/help/graphics.aspx
http://bitmiracle.com/pdf-library/help/images.aspx
PDF查看器组件在我们的计划中,但目前Docotic.Pdf不提供此类功能。
答案 1 :(得分:2)
如何寻找更好的方法来计算混合大小/样式文本的宽度,而不是寻找其他库?
float width = ColumText.getWidth(phrase);
Phrase使用各种文本布局函数和属性扩展ArrayList。段落扩展了短语。每个块都有一个特定的Font
,它有自己的颜色,大小和基础PDF字体。每个块都有自己的“文本上升”来调整其基线。
您使用的是什么版本的iText? ColumnText已经存在了很长一段时间。
所以你想在正常和&之间进行字距调整。上标字母?这对我来说听起来不是一个好主意。字距调整是一种调整,因此'T'可以突出“j”。字距调整值假定共享基线和字体大小。在处理上标文本时,您永远不会共享基线,并且几乎肯定会有不同的字体大小。即使你认为使用这些值是个好主意(我也不同意),你会在基本文本的磅值或上标的字体大小中使用吗?
我的观点是,我认为你的目标(使用普通文本修改上标/下标文本边界)会导致更糟糕的布局,而不是更好。
还是我误解了你?让我重新阅读你的评论:
但是当你还要在页面上放置包含上标的文本时,你需要使用PdfContentByte。
不完全确定你的意思。如果您想将文字放在页面上的任意位置,是的,您几乎需要使用PdfContentByte
。
使用它时,我没有找到同时打印包含上标的复杂文本的方法。
给定“show text”命令中的所有文本必须共享相同的字体/大小/颜色/等。这就是 PDF 的工作方式,它不是iText的一些限制。
我认为它只允许在当时打印一个文本块。
正确。
所以我不能用上标考虑字距来测量文本,然后把它放在页面上的某个位置
您需要将不同块的所有宽度添加到一起。我无法相信正常文本和上标文本之间的字距调整是一个好主意,但显示问题的PDF样本可能会说服我。
在我看来,你需要使用BaseFont.getWidthPointKerned(String text, float fontSize)
。上标,下标或正常,它都是关于点大小和字体的。如果您绝对坚持,您可以使用BaseFont.getKerning(int c1, int c2)
来获取同一字体中任意两个字母之间的字距调整值,并使用它来确定块间字距调整。
使用iText& amp;绘制文本的另一种方法PdfContentByte
与ColumnText
一致。我相信iText在布置段落时会使用ColumnText,但我必须仔细查看代码。
无论如何,您的代码可能如下所示:
ColumnText colTx = new ColumnText(contByte);
// paragraphs are phrases.
colTx.addText(phraseWithSuperAndSubScriptStuff);
colTx.setSimpleColumn(llx, lly, urx, ury);
colTx.go();
答案 2 :(得分:1)
如果您正在使用WPF,并且想要创建打印质量文档,那么内置的FixedDocument和XPS技术可能就是您应该学习的内容。由于您最终可以访问对象模型中的整个FixedDocument,因此它也可以告诉您宽度数字。我还没有尝试过。
答案 3 :(得分:1)
我们的产品PDFOne .NET可能符合您的要求。它附带免版税的商业许可证。
PDFOne .NET还附带PDF打印机组件和PDF查看器组件。
免责声明:我为Gnostice工作。
答案 4 :(得分:1)
我认为你可能会过度思考你的问题,而WPF具有很强的打印能力。 您可以以非常简单的方式打印任何视觉(视觉几乎都是WPF类),就像您在屏幕上看到它们一样。这里有一个很好的教程:http://www.switchonthecode.com/tutorials/printing-in-wpf
答案 5 :(得分:1)
听起来你需要获得一些GDI +的经验。
我在一家抵押贷款公司工作,他们非常关注他们希望如何制定报告。降低像素精度。不幸的是,GDI +并不能很好地测量Text。因此,更好的选择是使用Windows API
[DllImport("gdi32.dll")]
static extern bool GetTextExtentPoint(IntPtr hdc, string lpString,
int cbString, ref Size lpSize);
传递正在绘制的位图的句柄。更加准确。
或者你可以考虑使用TextRenderer
http://msdn.microsoft.com/en-us/library/system.windows.forms.textrenderer(v=VS.80).aspx
我无法说出它的准确程度。
答案 6 :(得分:0)
对于它的价值,我认为iTextSharp是最简单的一个。你可以在所有这些中做你想做的事,但它们各有利弊。