8

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

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

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

场景一:

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

场景二:

  1. 我创建了一个文本,其中的某些部分用上标表示。文本的所有部分(正常和上标)都使用相同(但可变)的字体。
  2. 我问图书馆如果这个文本在打印时的宽度是多少。我得到了正确的答案,它也考虑了普通文本和上标之间的字距调整。
  3. 我在应打印此文本的页面上计算位置([X,Y] 坐标)(使用步骤 2 中的宽度)。我让图书馆在这个位置打印它。打印在页面上的宽度与上一步中库返回的宽度完全相同。

第二种情况的注意事项:我有一些上标部分的文本 - 示例AAA{v-superscript text}BBB{}大括号中的文本是上标)。库需要能够使用正确的kerning打印此文本。A如果没有正确的字距调整,last和 first superscript之间的间距将与vlast superscriptt和 first之间的间距相同B。对于用户来说,看起来A和上标之间有一个空格,v但在最后一个上标字母之后没有空格。所以文字看起来很难看。如果库要正确处理此问题,它将有方法AAA{v-superscript text}BBB一次打印整个文本,并指定其中一部分为上标。然后它将在普通文本和上标之间使用正确的字距调整。

场景 3:

  1. 我想在页面的确切点上打印由线条、圆圈、实心圆圈、字母和贝塞尔曲线组成的图片。我需要指定线条和圆圈的宽度。所有形状都需要以像素精度打印。

该库应该是免费的,而不是 GPL(LGPL 可以)。有什么可以让我做我需要的事情吗?可以用 iTextSharp(LGPL 而非 AGPL 的 4.1.6 版)来完成吗?或者也许是固定文件?感谢您的任何建议。


原始问题:

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

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

这是我的 API 要求:

  1. 返回给定字符串和给定字体的确切宽度的函数,其中文本应该出现
  2. 将文本定位到页面上的确切位置的能力
  3. 在超级脚本中包含部分文本
  4. 获取某些文本的确切宽度的函数,该文本的某些部分在上标中
  5. 添加图片的能力甚至更好的选择来绘制简单的图形(给定厚度的线,给定半径/直径的实心圆)

它不必是用于创建 PDF 文档的库 - 任何其他“所见即所得”的文档格式也可以。如果有可以显示此类文档的 WPF 组件,那将是一个优势。我知道有 iTextSharp,但用 iTextSharp 实现 4. 要求并不容易。当然,一些满足上述要求的 PDF 生成库也将是很好的解决方案。

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

4

7 回答 7

4

您可以查看Docotic.Pdf 库(免责声明:我为 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() 方法将产生不正确的结果。

有解决方法:

- 分别测量用不同字体绘制的字符串的每个部分,然后对所有宽度求和。

- 如果你想获得绘制文本的宽度,你可以简单地从绘制后的最终文本位置中减去初始文本位置。

  • 添加图片的能力甚至更好的选择来绘制简单的图形(给定厚度的线,给定半径/直径的实心圆)

支持的。查看这些示例:
https ://github.com/BitMiracle/Docotic.Pdf.Samples/tree/master/Samples/Graphics
https://github.com/BitMiracle/Docotic.Pdf.Samples/tree/master/Samples/图片


PDF 查看器组件在我们的计划中,但目前 Docotic.Pdf 不提供此类功能。

更新:您现在可以使用 Docotic.Pdf 栅格化、渲染或打印 PDF 文档。查看以下文章:
https ://bitmiracle.com/pdf-library/convert-pdf-to-image.aspx
https://bitmiracle.com/pdf-library/draw-print-pdf.aspx

于 2011-04-12T17:42:04.853 回答
2

与其寻找其他库,不如寻找一种更好的方法来计算混合大小/样式文本的宽度?

float width = ColumText.getWidth(phrase);

Phrase 使用各种文本布局功能和属性扩展了 ArrayList。段落扩展短语。每个块都有一个特定Font的颜色、大小和基础 PDF 字体。每个块都有自己的“文本上升”来调整其基线。

您使用的是哪个版本的 iText?ColumnText 已经存在了相当长的一段时间。


所以你想在普通字母和上标字母之间调整字距?对我来说,这听起来不是一个好主意。字距调整是一种调整,例如,“T”可以突出“j”。字距调整值假定共享基线和字体大小。您永远不会共享基线,并且在处理上标文本时几乎肯定会有不同的字体大小。即使您认为使用这些值是一个好主意(我不同意),您是在基本文本的磅值还是上标的字体大小中调整字距?

我的观点是,我认为您的目标(带有普通文本的紧缩上标/下标文本边界)将导致更糟糕的布局,而不是更好。

还是我误会你了?让我重新阅读您的评论:

但是,当您还想在页面上放置包含上标的文本时,您需要使用 PdfContentByte。

不完全确定你的意思。如果您想将文本放置在页面上的任意位置,是的,您几乎需要使用PdfContentByte.

使用它时,我没有找到一次打印包含上标的复杂文本的方法。

给定“显示文本”命令中的所有文本必须共享相同的字体/大小/颜色/等。这就是PDF的工作方式,它不是 iText 的一些限制。

我认为它只允许同时打印一个文本块。

正确的。

所以我不能用上标测量文本,考虑到字距调整,然后把它放在页面上的某个位置

您需要将不同块的所有宽度加在一起。我不敢相信普通文本和上标文本之间的字距调整是个好主意,但是显示问题的 PDF 示例可能会说服我。

在我看来,您需要使用BaseFont.getWidthPointKerned(String text, float fontSize). 上标、下标或法线,都是关于磅值和字体的。如果您绝对坚持,您可以使用BaseFont.getKerning(int c1, int c2)获取同一字体内任意两个字母之间的字距调整值,并使用它来确定块间字距调整。


使用 iText & 绘制文本的另一种方法PdfContentByte是使用ColumnText. 我相信 iText 在布局段落时使用 ColumnText,但我必须查看代码才能确定。

无论如何,您的代码可能看起来像这样:

ColumnText colTx = new ColumnText(contByte);
// paragraphs are phrases.
colTx.addText(phraseWithSuperAndSubScriptStuff);
colTx.setSimpleColumn(llx, lly, urx, ury);
colTx.go();
于 2011-04-12T23:19:38.190 回答
1

我认为你可能想多了你的问题,而 WPF 有很好的打印能力。您可以以非常简单的方式完全按照您在屏幕上看到的任何视觉对象(视觉对象几乎是所有 WPF 类)打印它们。这里有一个很好的教程:http ://www.switchonthecode.com/tutorials/printing-in-wpf

于 2011-04-21T01:43:41.823 回答
1

我们的产品PDFOne .NET可以满足您的要求。它带有免版税的商业许可。

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

PDFOne .NET 还附带了一个 PDF 打印机组件和 PDF 查看器组件。

免责声明:我为 Gnostice 工作。

于 2011-04-12T05:10:24.887 回答
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

我不能对它的准确度做出任何声明。

于 2011-04-22T05:57:51.260 回答
1

这是MSDN 上关于构造 FixedDocument 对象的文章。

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

于 2011-04-12T02:20:59.323 回答
0
  1. LaTeX:用于在生产中生成 PDF 的 LaTeX
  2. 对于像 Aspose 这样的付费库:http ://www.aspose.com/categories/.net-components/aspose.pdf-for-.net/default.aspx
  3. 带有良好 CSS 的纯 HTML 也可以很好地工作。
  4. 微软开放 XML:http: //msdn.microsoft.com/en-us/library/bb448854.aspx

对于它的价值,我认为 iTextSharp 是其中最简单的一个。你可以在所有这些中做你想做的,但它们各有利弊。

于 2011-04-12T02:02:10.527 回答