用于排版文档(PDF 或类似)的 .NET 库?
编辑:更好的解释: 在为这个问题设置赏金之前,我想更清楚地说明我需要什么:
我需要 .NET 库来生成可打印文档。用户应该能够使用我的应用程序或使用外部工具(如 Adobe Acrobat reader)打印与他们看到的完全相同的文档。生成PDF文档不必是库,任何满足上述条件的文档格式都可以。
我需要该库支持以下场景:
场景 1:
- 我以某种字体和颜色创建文本。
- 如果打印此文本,我会向图书馆询问宽度。
- 我根据 2 中的信息计算该文本的位置(页面上的 [X,Y] 坐标),并让库在页面上的这个位置打印。
场景 2:
- 我创建一个文本,其中某些部分位于上标中。文本的所有部分(正常和上标)均采用相同(但可变)的字体。
- 我问图书馆打印此文本时的宽度是多少。我得到了正确的答案,该答案还考虑了普通文本和上标之间的字距调整。
- 我计算应打印此文本的页面上的位置([X,Y] 坐标)(使用步骤 2 中的宽度)。我让图书馆在这个位置打印它。打印在页面上的宽度与上一步中库返回的宽度完全相同。
第二种情况的注意事项:我的文本中的某些部分位于上标中 - 例如 AAA{v-superscript text}BBB
(其中 {}
中的文本大括号是上标)。该库需要能够使用正确的字距调整来打印此文本。如果没有正确的字距调整,最后一个 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的4.要求。当然,一些满足上述要求的PDF生成库也将是很好的解决方案。
感谢您的任何建议,我也很乐意提供详细信息或更清晰的解释。
EDIT: Better explanation:
Before setting a bounty for this question I want to state clearer what I need:
I need .NET library for generating printable documents. Users should be able to print exactly the same document that they see either using my application or using external tool (like Adobe Acrobat reader). It does not have to be library for generating PDF documents, any document format that satisfies above condition will do.
I need the library to support following scenarios:
Scenario 1:
- I create text in some font and color.
- I ask the library for the width if this text if printed.
- I compute position([X,Y] coordinates on page) of this text based on information from 2. and have the library to print in at this position on a page.
Scenario 2:
- I create a text with some parts of it in superscript. All parts of text (normal and superscript) are in same (but variable) font.
- I ask the library what is the width if this text when printed. I get correct answer that also takes kerning between normal text and superscript into account.
- I compute position([X,Y] coordinates) on a page where this text should be printed (using its width from step 2.). I let the library to print it at this position. Printed on the page it has exactly the width that was returned by library in previous step.
Note for second scenario: I have text with some parts in superscript - example AAA{v-superscript text}BBB
(where text in {}
braces is superscript). The library needs to be able to print this text using correct kerning. Without right kerning there will be the same gap between last A
and first superscript v
as between last superscript t
and first B
. For the user it will look like there is a space between A
and superscript v
but no space after the last superscript letter. So the text will look ugly. If the library is to handle this correctly it would have method to print the whole text AAA{v-superscript text}BBB
at once with specification that a part of it is in superscript. Then it would use correct kerning between normal text and superscript.
Scenario 3:
- I want to print picture that consists of lines, circles, filled circles, letters and bezier curves on exact point in a page. I need to specify width of lines and circles. All shapes needs to be printed in pixel precision.
The library should be free of charge and not GPL (LGPL is ok). Is there something that allows me to do what I need ? Can it be done with iTextSharp (version 4.1.6 that is LGPL not AGPL)? Or perhaps with Fixed document ? Thank you for any suggestions.
Original question:
I need to typeset complex documents in .NET (C#) application for the user. Primary use of those documents will be for printing.
Documents will contain text and simple generated graphics. Layout of text and graphic will be complex and needs to be computed (in another words text position in document needs to be controlled by my code, it will not be done automatically by chosen library).
Here are my API requirements:
- function that returns exact width for given string and given font in which text should appear
- ability to position text to exact position on the page
- have text with some part of it in super script
- function to get exact width of some text that has some part of it in superscript
- ability to add pictures or even better option to draw simple graphics (line of given thickness, filled circle of given radius/diameter)
It does not have to be library for creating PDF documents - any other "what you see is what will be printed" document format will also do. If there is WPF component that can displays such documents it is an advantage. I know there is iTextSharp but is not easy to achieve 4. requirement with iTextSharp. Of course some PDF generation library that satisfies requirements above will be great solution too.
Thank you for ANY suggestions, I'm also happy to provide details or clearer explanation.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
您可以查看Docotic.Pdf Library(免责声明:我为 Bit Miracle 工作)。
它具有用户友好的 API 和一组良好的示例,您可以在线查看或在示例查看器应用程序中运行。
它还满足您的要求:
您可以使用 PdfCanvas.MeasureText() 方法。
有许多重载允许在任意位置或区域显示文本。
https://bitmiracle.com/pdf-library/api/pdfcanvas-drawstring
https://bitmiracle.com/pdf-library/api/pdfcanvas-drawtext
PdfCanvas.TextRise 属性允许显示上标文本。您可以将它与 PdfCanvas.FontSize 属性结合使用来控制上标文本的大小。
代码示例:
https://github.com/BitMiracle/Docotic。 Pdf.Samples/tree/master/Samples/Text/TextRise
如果您将为上标文本使用不同的字体或字体大小,则直接调用 PdfCanvas .MeasureText() 方法将产生不正确的结果。
有解决方法:
- 分别测量用不同字体绘制的字符串的每个部分,然后将所有宽度相加。
-如果您想获得绘制文本的宽度,您可以简单地从绘制后的最终文本位置中减去初始文本位置。
。看看这些样本:
https://github.com/BitMiracle/Docotic.Pdf。示例/树/主/示例/图形
https://github.com/BitMiracle/Docotic.Pdf。 Samples/tree/master/Samples/Images
PDF 查看器组件已在我们的计划中,但目前 Docotic.Pdf 不提供此类功能。
更新:您现在可以使用 Docotic.Pdf 光栅化、渲染或打印 PDF 文档。请参阅以下文章:
https://bitmiracle.com/pdf-library/pdf-image/convert
https://bitmiracle.com/pdf-library/draw-print-pdf
You can look to Docotic.Pdf Library (disclaimer: I work for Bit Miracle).
It has user-friendly API and good set of samples that you can view online or run in sample viewer application.
Also it satisfies your requirements:
You can use the PdfCanvas.MeasureText() method for this.
There are many overloads that allows to show text in arbitrary position or area.
https://bitmiracle.com/pdf-library/api/pdfcanvas-drawstring
https://bitmiracle.com/pdf-library/api/pdfcanvas-drawtext
The PdfCanvas.TextRise property allows to show superscript text. You can use it in combination with PdfCanvas.FontSize property for control a size of superscript text.
The code sample:
https://github.com/BitMiracle/Docotic.Pdf.Samples/tree/master/Samples/Text/TextRise
If you will use different font or font size for superscript text the direct call of PdfCanvas.MeasureText() method will produce incorrect results.
There are workarounds:
-measure each part of string drawn with different fonts separately and then sum all widths.
-if you want to get width of drawn text you can simply subtract initial text position from the final text position after drawing.
Supported. Look at these samples:
https://github.com/BitMiracle/Docotic.Pdf.Samples/tree/master/Samples/Graphics
https://github.com/BitMiracle/Docotic.Pdf.Samples/tree/master/Samples/Images
PDF viewer component is in our plans, but currently Docotic.Pdf doesn't offer such functionality.
Update: You can now rasterize, render, or print PDF documents using Docotic.Pdf. Look at the following articles:
https://bitmiracle.com/pdf-library/pdf-image/convert
https://bitmiracle.com/pdf-library/draw-print-pdf
与其寻找其他库,不如寻找一种更好的方法来计算混合大小/样式文本的宽度?
Phrase 使用各种文本布局函数和属性扩展了 ArrayList。段落扩展了短语。每个块都有一个特定的
Font
,具有自己的颜色、大小和底层 PDF 字体。每个块都有自己的“文本上升”来调整其基线。您使用什么版本的 iText? ColumnText 已经存在很长一段时间了。
所以你想要正常和宽之间的字距调整。上标字母?对我来说这听起来不是一个好主意。字距调整是一种调整,例如“T”可以悬垂在“j”之上。字距调整值假定共享基线和字体大小。您永远不会共享基线,并且在处理上标文本时几乎肯定会使用不同的字体大小。即使您认为使用这些值是个好主意(我不同意),您是否会调整基本文本的磅值或上标的字体大小?
我的观点是,我认为您的目标(使用普通文本调整上标/下标文本边界)将导致更糟糕的布局,而不是更好。
还是我误会你了?让我重读一下您的评论:
不完全确定你的意思。如果您想将文本放置在页面上的任意位置,是的,您几乎需要使用
PdfContentByte
。给定“显示文本”命令中的所有文本必须共享相同的字体/大小/颜色/等。这就是 PDF 的工作方式,它不是 iText 的某些限制。
正确的。
您需要将不同块的所有宽度添加在一起。我不敢相信普通文本和上标文本之间的字距调整是一个好主意,但显示问题的 PDF 示例可以说服我否则。
在我看来,您需要使用 BaseFont.getWidthPointKerned(String text, float fontSize) 。上标、下标还是普通,都与磅值和字体有关。如果您绝对坚持,您可以使用 BaseFont.getKerning(int c1, int c2) 来获取同一字体内任意两个字母之间的字距调整值,并使用该值确定块间字距调整。
使用 iText & 绘制文本的另一种方法
PdfContentByte
与ColumnText
。我相信 iText 在布局段落时使用 ColumnText,但我必须查看代码才能确定。无论如何,您的代码可能看起来像这样:
Rather than looking for other libraries, how about looking for a better way to compute the width of mixed-size/style text?
Phrase extends ArrayList with various text layout functions and attributes. Paragraph extends Phrase. Each chunk has a specific
Font
with its own color, size, and underlying PDF font. Each chunk has its own "text rise" to adjust its baseline.What version of iText are you using? ColumnText has been around for Quite Some Time.
So you want kerning between normal & superscript letters? That doesn't sound like a very good idea to me. Kerning is an adjustment so 'T' can overhang "j" for example. Kerning values assume a shared baseline and font size. You'll never share a baseline, and almost certainly have different font sizes when dealing with superscript text. And even if you decide it's a good idea to use those values (and I'd disagree), do you kern in the base text's point size, or the superscript's font size?
My point is that I think your goal here (kerned superscript/subscript text boundaries with normal text) is going to result in worse layout, not better.
Or am I misunderstanding you? Let me re-read your comment:
Not entirely sure what you mean there. If you want to place text in an arbitrary location on the page, yes, you're pretty much required to use
PdfContentByte
.All the text in a given "show text" command must share the same font/size/color/etc. That's the way PDF works, its not some limitation of iText.
Correct.
You need to add all the widths of the different chunks together. I can't believe kerning between normal and superscript text is a good idea, but a PDF sample showing the problem could persuade me otherwise.
It seems to me you need to use
BaseFont.getWidthPointKerned(String text, float fontSize)
. Superscript, subscript, or normal, it's all about the point size and font. And if you Absolutely Insist, you can useBaseFont.getKerning(int c1, int c2)
to get the kerning value between any two letters within the same font, and use that to determine inter-chunk kerning.Another way to draw text with iText &
PdfContentByte
is withColumnText
. I believe iText uses ColumnText when laying out paragraphs, but I'd have to go look at the code to be sure.At any rate, your code might look something like this:
这里有一篇 MSDN 上关于构造固定文档对象的文章。
如果您正在使用 WPF,并且想要创建打印质量文档,那么内置的固定文档和 XPS 技术可能是您应该学习的。由于您最终可以访问对象模型中的整个固定文档,因此它也可能会告诉您宽度数字。我还没有尝试过。
Here is an article on constructing FixedDocument objects on MSDN.
If you are using WPF, and you want to create Print Quality documents, the FixedDocument and XPS technologies built in are probably what you should be learning. And since you can eventually access the entire FixedDocument in the object model, it may tell you your width numbers as well. I haven't experimented with that yet.
我认为您可能想得太多了,而 WPF 具有出色的打印能力。
您可以以非常简单的方式打印任何视觉效果(视觉效果几乎都是 WPF 类),就像您在屏幕上看到的那样。这里有一个很好的教程: http://www.switchonthecode.com/tutorials/printing-在wpf中
I think you might be overthinking your problem, while WPF has great printing abilities.
You can print any visual (visuals are almost all WPF classes) exactly as you see them on the screen in a really easy way. There is a good tutorial here: http://www.switchonthecode.com/tutorials/printing-in-wpf
听起来您需要获得一些 GDI+ 经验。
我在一家抵押贷款公司工作,他们对报告的呈现方式非常挑剔。精确到像素精度。不幸的是,GDI+ 不能很好地测量文本。因此,更好的选择是使用 Windows API,
传递正在绘制的位图的句柄。更准确。
或者,您可以考虑使用 TextRenderer
http://msdn.microsoft.com/en-us/library/system.windows.forms.textrenderer(v=VS.80).aspx
我无法对其准确性做出任何声明。
Sounds like you need to get some experience in GDI+.
I worked for a mortgage company and they are very particular on how they want their reports laid out. Down to pixel precision. Unfortunately GDI+ does not measure Text very well. Therefore your better alternative would be to use windows API
you pass the handle of the Bitmap you are drawing on. Much more accurate.
alternatively you may look into using TextRenderer
http://msdn.microsoft.com/en-us/library/system.windows.forms.textrenderer(v=VS.80).aspx
I cant make any claims as to how accurate it is.
我们的产品 PDFOne .NET 可能会满足您的要求。它带有免版税的商业许可。
为此,您可以使用 PDFFont.GetTextWidth() 方法。
您可以使用众多 PDFDocument.WriteText() 重载之一来实现此
PDF 在其文本输出中没有任何此概念。在我们看来,超字符串只是另一个具有不同字体大小和位置的字符串。您只需要为此调用另一个文本输出即可。
请参阅之前的响应。
PDFOne .NET 还附带 PDF 打印机组件和 PDF 查看器组件。
免责声明:我为 Gnostice 工作。
Our product, PDFOne .NET may suit your requirements. It comes with royalty-free commercial license.
You can use the PDFFont.GetTextWidth() method for this.
You could use one of the many PDFDocument.WriteText() overloads for this
PDF does not have any this concept in its textouts. What appears to us as a superstring is just another string with a different font size and position. You just need to call another textout for this.
Refer previous response.
PDFOne .NET also comes with a PDF printer component and PDF viewer component.
DISCLAIMER: I work for Gnostice.
就其价值而言,我认为 iTextSharp 是其中最简单的一个。您可以在所有这些中做您想做的事,但它们各有利弊。
For what it's worth, I think iTextSharp is the easiest one of the bunch. You can do what you want in all of them, but they each have pros and cons.