用于排版文档的.NET库(PDF或类似文件)?

时间:2011-04-12 00:15:03

标签: .net pdf pdf-generation itextsharp kerning

编辑:更好的解释: 在为这个问题设定赏金之前,我想更清楚地说明我需要的东西:

我需要.NET库来生成可打印的文档。用户应该能够使用我的应用程序或使用外部工具(如Adobe Acrobat reader)打印他们看到的完全相同的文档。它不一定是用于生成PDF文档的库,任何满足上述条件的文档格式都可以。

我需要该库来支持以下场景:

情景1:

  1. 我用某种字体和颜色创建文字。
  2. 如果打印了这个文本,我会向图书馆询问宽度。
  3. 我根据来自2的信息计算此文本的位置(页面上的[X,Y]坐标),并让图书馆在页面上的这个位置打印。
  4. 情景2:

    1. 我用上标中的某些部分创建了一个文本。文本的所有部分(正常和上标)都是相同(但可变)的字体。
    2. 我问图书馆打印时这个文字的宽度是多少。我得到正确答案,正常文本和上标之间也需要kerning
    3. 我在应该打印此文本的页面上计算位置([X,Y]坐标)(使用步骤2中的宽度)。我让图书馆在这个位置打印出来。在页面上打印时,它具有上一步中库返回的宽度。
    4. 请注意第二种情况:我的文字包含上标中的某些部分 - 例如AAA{v-superscript text}BBB(其中{}括号中的文字是上标)。图书馆需要能够使用正确的kerning打印此文本。如果没有正确的字距调整,则上一个A和第一个上标v之间的差距将与上一个上标t和第一个B之间的差距相同。对于用户来说,看起来A和上标v之间有一个空格,但在最后一个上标字母后面没有空格。所以文字看起来很难看。如果库要正确处理它,它将有方法立即打印整个文本AAA{v-superscript text}BBB,并指定其中一部分是上标。然后它会在正常文本和上标之间使用正确的字距调整。

      情景3:

      1. 我想在页面中的精确点打印由线条,圆圈,实心圆圈,字母和贝塞尔曲线组成的图片。我需要指定线条和圆圈的宽度。所有形状都需要以像素精度打印。
      2. 图书馆应该是免费的而不是GPL(LGPL没问题)。有什么东西可以让我做我需要的东西吗?可以用iTextSharp(版本4.1.6即LGPL而不是AGPL)来完成吗?或者也许使用固定文档?感谢您的任何建议。


        原始问题:

        我需要为用户在.NET(C#)应用程序中排版复杂文档。这些文件的主要用途是用于印刷。

        文档将包含文本和简单生成的图形。文本和图形的布局将是复杂的并且需要计算(换句话说,文档中的文本位置需要由我的代码控制,它不会由选择的库自动完成。)

        以下是我的API要求:

        1. 返回给定字符串的精确宽度的函数和给出文本的给定字体
        2. 将文字定位到页面上的确切位置的能力
        3. 在超级脚本
        4. 中包含部分内容的文字
        5. 用于获取某些文本的精确宽度,该文本在上标
        6. 中具有部分文本
        7. 能够添加图片甚至更好的选项来绘制简单的图形(给定厚度的线,给定半径/直径的实心圆)
        8. 它不一定是用于创建PDF文档的库 - 任何其他“您看到的将要打印的内容”文档格式也可以。如果有WPF组件可以显示这样的文档,这是一个优势。 我知道有iTextSharp但是用iTextSharp来实现要求并不容易。当然,满足上述要求的一些PDF生成库也是很好的解决方案。

          感谢您提出任何建议,我也很乐意提供详细信息或更清晰的解释。

7 个答案:

答案 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;绘制文本的另一种方法PdfContentByteColumnText一致。我相信iText在布置段落时会使用ColumnText,但我必须仔细查看代码。

无论如何,您的代码可能如下所示:

ColumnText colTx = new ColumnText(contByte);
// paragraphs are phrases.
colTx.addText(phraseWithSuperAndSubScriptStuff);
colTx.setSimpleColumn(llx, lly, urx, ury);
colTx.go();

答案 2 :(得分:1)

关于在MSDN上构造FixedDocument对象的

Here is an article

如果您正在使用WPF,并且想要创建打印质量文档,那么内置的FixedDocument和XPS技术可能就是您应该学习的内容。由于您最终可以访问对象模型中的整个FixedDocument,因此它也可以告诉您宽度数字。我还没有尝试过。

答案 3 :(得分:1)

我们的产品PDFOne .NET可能符合您的要求。它附带免版税的商业许可证。

  1. 返回给定字符串的精确宽度的函数和给出文本的字体
    您可以使用PDFFont.GetTextWidth()方法。
  2. 将文本定位到页面上的确切位置的能力
    您可以使用许多PDFDocument.WriteText()重载中的一个
  3. 在超级脚本中有部分内容的文本
    PDF在其短信中没有任何这个概念。我们看起来像超级字符串只是另一个字符大小和位置不同的字符串。你只需要为此调用另一个文本输出。
  4. 用于获取某些文本的确切宽度,该文本在上标中具有部分文本
    请参阅上一个回复。
  5. 能够添加图片甚至更好的选项来绘制简单的图形(给定厚度的线,给定半径/直径的实心圆) - PDFOne .NET具有渲染图像,正方形,矩形,弧形, Bezeir曲线,椭圆,圆形,矩形,折线,多边形,矩形,水印,图章,几种注释,......
  6. 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)

  1. LaTeX:LaTeX for PDF generation in production
  2. 对于像Aspose这样的付费库:http://www.aspose.com/categories/.net-components/aspose.pdf-for-.net/default.aspx
  3. 具有良好CSS的纯HTML也可以很好地工作。
  4. Microsoft Open XML:http://msdn.microsoft.com/en-us/library/bb448854.aspx
  5. 对于它的价值,我认为iTextSharp是最简单的一个。你可以在所有这些中做你想做的事,但它们各有利弊。