2011-04-12 19 views
8

編輯:更好的解釋: 之前設定的賞金這個問題,我想更清楚地說明我需要什麼:用於排版文檔的.NET庫(PDF或類似)?

我需要.NET庫生成可打印的文檔。用戶應該能夠使用我的應用程序或使用外部工具(如Adobe Acrobat reader)打印完全相同的文檔。它不一定是用於生成PDF文檔的庫,任何滿足上述條件的文檔格式都可以。

我需要的庫,支持以下情形:

方案1:

  1. 我創造一些字體和顏色的文本。
  2. 我問圖書館的寬度,如果這個文本,如果打印。
  3. 我基於2中的信息計算此文本的位置(頁面上的[X,Y]座標),並讓庫打印在頁面上的此位置。

方案2:

  1. 我創建的標它的某些部分文本。文本的所有部分(正常和上標)都是相同的(但可變)字體。
  2. 我問圖書館什麼是寬度,如果這個文本打印時。我得到正確的答案,也考慮到正常文本和上標之間的kerning
  3. 我在要打印文本的頁面上計算位置([X,Y]座標)(使用步驟2中的寬度)。我讓圖書館在這個位置打印它。在頁面上打印,它具有上一步庫中返回的寬度。

注意的第二個場景:我有在標某些部分的文字 - 例如AAA{v-superscript text}BBB(其中{}括號文字上標)。該庫需要能夠使用正確的kerning打印此文本。如果沒有正確的調整,最後的上標t和第一個B之間的最後A和第一上標v之間將會有相同的差距。對於用戶來說,看起來在A和上標v之間有一個空格,但在最後一個上標字母后沒有空格。所以文字看起來很醜。如果庫要正確處理它,它將有方法一次打印整個文本AAA{v-superscript text}BBB,並且其中的一部分在上標中。然後它會在正常文本和上標之間使用正確的字距。

方案3:

  1. 我想打印的圖片是由直線,圓,實心圓,字母和Bezier曲線上的一個頁面確切點。我需要指定線條和圓圈的寬度。所有形狀都需要以像素精度打印。

該庫應該是免費的,而不是GPL(LGPL是好的)。有什麼可以讓我做我需要的嗎?可以使用iTextSharp(版本4.1.6,LGPL不是AGPL)來完成嗎?或者也許與固定文件?謝謝你的任何建議。


原題:

我需要排版複雜的文檔在.NET(C#),爲用戶應用。這些文件的主要用途是打印。

文檔將包含文本和簡單的生成圖形。文本和圖形的佈局將很複雜,需要進行計算(換句話說,文檔中的文本位置需要由我的代碼控制,它不會由所選庫自動完成)。

這裏是我的API的要求:

  1. 函數返回給定的字符串和詳細的寬度定的字體在文本應該出現
  2. 來定位頁面
  3. 有文字上的文本到確切位置的能力其中的一部分在超級腳本中
  4. 函數獲得一些文字的確切寬度,其中有一部分在上標
  5. 添加圖片的能力甚至更好的選項d原始簡單圖形(給定厚度的線,給定半徑/直徑的實心圓)

它不一定是用於創建PDF文檔的庫 - 任何其他「你看到的是將要打印的」文檔格式也做。如果有WPF組件可以顯示這些文檔,這是一個優勢。 我知道有iTextSharp,但不容易實現4.需求與iTextSharp。當然一些滿足上述要求的PDF生成庫也是很好的解決方案。

感謝您的任何建議,我也很樂意提供詳細信息或更清晰的解釋。

+1

你看過XPS/XpsDocumentWriter/etc。然而? – 2011-04-12 00:20:06

+0

@Logan Capaldo:這個名字對我來說聽起來很熟悉......如果是那種具有原生WPF控件來顯示它的格式,比我之前看過的格式要好。但我沒有弄清楚在WPF中是否有簡單的方法來生成這樣的文檔。我有問題沒有關於它的答案在這裏:http://stackoverflow.com/questions/4634445/how-to-work-with-fixedpage。 – drasto 2011-04-12 00:27:47

+0

@Logan Capaldo:但是XPS文件不是固定的嗎?所以它不顯示完全相同的佈局將被打印? – drasto 2011-04-12 00:40:57

回答

0
  1. 乳膠: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. 微軟的Open XML:http://msdn.microsoft.com/en-us/library/bb448854.aspx

對於它的價值,我覺得iTextSharp的是一羣最容易的一個。你可以在所有人中做你想做的事,但他們每個人都有優點和缺點。

+1

乳膠:我需要編程訪問將在我的文檔中計算佈局的字符串寬度。這不能用乳膠完成。 Html:我在哪裏可以得到字符串的寬度?打開XML - 查看以前對原始問題的評論。 – drasto 2011-04-12 02:10:20

+0

我遠離LaTeX的專家,但我確信你可以做任何你想做的事情。您可以按照此處所述指定節點的寬度:http://tex.stackexchange.com/questions/7660/tikz-applying-width-to-nodes-programmatically-and-undefined-control-sequence-p Html:用css控制字體,並根據長度和字體信息計算字符串的寬度。 Open XML:我連接的SDK非常豐富,我相信你可以做你需要的。 就像我說過的,你可以做所有圖書館需要的東西,它可能需要一些創造力和努力工作。我不認爲這裏有一個簡單的方法。 – Milimetric 2011-04-12 02:16:40

+1

我很清楚在LaTeX中可以做什麼,也不能做什麼。您可以在LaTeX中使用某些字符串的信息寬度,但不能從.NET代碼的外部訪問它。我不能讓LaTeX在沒有.NET的情況下單獨進行佈局,因爲我的佈局對於LaTeX來說太複雜了 - 我需要全功能的編程語言來計算它。不,你不能在LaTeX中做任何你想做的事情。這是你不能做的:http://stackoverflow.com/questions/2599644/how-to-keep-material-on-one-double-page-in-latex。這就是我無法使用它的原因。 – drasto 2011-04-12 02:49:25

1

Here is an article構建MSDN上的FixedDocument對象。

如果您正在使用WPF,並且想要創建打印質量文檔,則內置的FixedDocument和XPS技術可能是您應該學習的內容。由於您最終可以訪問對象模型中的整個FixedDocument,因此它可能會告訴您寬度數字。我還沒有嘗試過。

+0

在我決定使用它之前,我需要知道可以做我需要做的事情。所以我需要知道如何獲取文本寬度信息,以及如何排版超級腳本。以及如何測量超級腳本文本。 – drasto 2011-04-21 02:53:24

1

我們的產品,PDFOne .NET可能適合您的要求。它帶有免版稅的商業許可證。

  1. 函數返回給定的字符串和詳細的寬度定的字體在文本應該出現
    可以使用PDFFont.GetTextWidth()方法用於此。
  2. 來定位頁面
    您可以使用許多PDFDocument.WriteText之一(文本到確切位置的能力)重載這個
  3. 有文字與超級腳本的某一部分
    PDF不在其文字中有這個概念。在我們看來,超字符串只是另一種字體大小和位置不同的字符串。你只需要爲此調用另一個文本。
  4. 函數獲得一些文字的確切寬度,其中有一部分在上標
    請參閱前面的回覆。
  5. 添加圖片的能力,甚至更好的選項來繪製簡單的圖形(給定厚度的線,給定半徑/直徑的實心圓)- PDFOne .NET已經呈現圖像,正方形,矩形,圓弧,Bezeir曲線,橢圓,圓形,矩形,多段線,多邊形,矩形,水印,郵票,幾種類型的註釋,...

PDFOne .NET還附帶了PDF打印機組件和PDF閱讀器組件。

免責聲明:我爲Gnostice工作。

+0

+1好答案。然而,當你在3中寫出上標是另一個文本時,我認爲這不是我所期望的。如果我只添加較小的文字作爲上標,它會看起來很醜,因爲在正常文本和上標之間沒有字距。考慮到'A^v'的例子,'A'和上標'v'之間會有很大的空間。在另一種情況下,'E^b'在之前的情況下會有更少的空間。所以我需要不能正確定位上標,沒有字距信息。然後我也需要這些信息來衡量它。 – drasto 2011-04-12 14:16:44

+1

我必須糾正自己有關上標和下標文本。我將這個問題提交給我們的開發人員(post-answer),他們說PDF不需要單獨的文本輸出,也就是說,它可以通過單個文本輸出來實現。我們將在即將到來的版本中添加對這些字符串的支持。目前,我們的產品需要單獨的文本輸出。 – BZ1 2011-04-13 07:14:21

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()方法將產生不正確的結果。

有替代方法:

-measure串的每一部分具有不同的字體單獨繪製再總結所有寬度。

如果你想獲得繪製文本的寬度,你可以簡單地從繪圖後的最終文本位置減去初始文本位置。

  • 添加圖片或甚至更好的選擇繪製簡單圖形(給定厚度的線,給定的半徑/直徑的實心圓)

支持能力。看看樣品:

http://bitmiracle.com/pdf-library/help/graphics.aspx

http://bitmiracle.com/pdf-library/help/images.aspx


PDF查看器組件是在我們的計劃,但目前Docotic.Pdf不提供這樣的功能。

+0

有沒有我可以看到這個例子的輸出爲你提供的上標的地方:http://bitmiracle.com/pdf-library/help/text-rise.aspx?你有免費的試用版/演示版/ GPL版本嗎? – drasto 2011-04-22 09:08:43

+2

當然。你可以[下載和評估Docotic](http://bitmiracle.com/downloads.aspx)。它帶有示例查看器和Visual Studio 2005-2010的樣本集。評估版本有一些限制,你可以閱讀詳細信息[here](http://bitmiracle.com/pdf-library/trial-restrictions.aspx) – 2011-04-22 13:37:50

2

與其尋找其他庫,不如尋找更好的方法來計算混合大小/樣式文本的寬度?

float width = ColumText.getWidth(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的& PdfContentByteColumnText。我相信iText在佈置段落時使用了ColumnText,但我必須去查看代碼才能確定。

在任何情況下,你的代碼可能是這個樣子:

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

@Mark Storer:我與iTextSharp的問題是,當你想要文本在不在上標的文字後面跟着上標。當您以標準方式使用iTextSharp時,它會做出正確的調整。但是當你也想把它定位在包含上標的文本上時,你需要使用'PdfContentByte'。當使用它時,我沒有找到打印包含上標的複雜文本的方法。我認爲它只允許在一段時間內打印一個文本塊。所以我不能用帶有上下標的文本來衡量文本,然後將它放在頁面上的某個位置...... – drasto 2011-04-14 00:16:54

+0

...沒有將它分割成塊和打印單獨的塊在頁面上。但是這樣我在這些塊之間(在上標和非上標文本之間的邊界)鬆了一會兒。所以結果是文本看起來很糟糕(沒有在上標之前徘徊),但我可以測量它並在指定的位置打印 - 或者它看起來不錯,我可以測量它,但它不能打印在頁面上的自定義位置上我不能在'PdfContentByte'中使用'ColumText')。我可以下載最新版本的iTextSharp,這不是問題。現在我正在使用1歲的版本。 – drasto 2011-04-14 00:23:07

+0

@Mark Storer現在只是我提到你編輯了你的答案。你正確理解我的意見。有一個錯字,但你說得對。關於普通文本和上標文本之間的區別:上次當我測試如何使用PdfContentByte打印包含正常和上標部分的文本時(我可以在任意位置打印它)我做了以下操作:打印普通文本'普通文本'在'[30,30]'。使用'BaseFont.getWidthPointKerned'測量'普通文本'。可以說,返回的值是「101」。所以我在[131,30]上使用相同的... – drasto 2011-04-22 10:50:04

1

我想你可能會得太多你的問題,而WPF具有很大的印刷能力。 您可以完全按照您在屏幕上以非常簡單的方式看到它們的方式打印任何視覺效果(視覺效果幾乎都是WPF類)。這裏有一個很好的教程:http://www.switchonthecode.com/tutorials/printing-in-wpf

+1

看起來不錯,但我怎麼能在WPF中有一些帶有上標的文本?我不認爲有可能有一個'標籤',在上標(和kerned)中有一些文字部分。那麼我將如何測量文字呢?只是通過獲得Label的'AcctualWidth'的值? – drasto 2011-04-21 02:55:56

+1

嗨,我沒有嘗試它自己,但我認爲這是一個解決方案上標與普通文本混合:http://stackoverflow.com/questions/2095583/set-superscript-and-subscript-in-formatted-文本中,WPF。 對於寬度來說,是的,它或多或少都很簡單。 WPF可以測量任何視覺的寬度,並從它的屬性中獲得。我編寫了類似的東西,但我沒有在這裏。我稍後會在家檢查。 祝你好運! – 2011-04-24 18:40:47

+0

@tinchou:很好的鏈接!再次,我越來越喜歡這個......我幾乎決定使用'iTextSharp'並嘗試讓Mark Storer的建議奏效,但現在我正在重新考慮它。任何你可以提供的代碼都是非常有用的。視覺效果可以轉換爲'FixedDocument',那是對的嗎? – drasto 2011-04-24 21:29:26

1

聽起來就像你需要在GDI +中獲得一些經驗。

我曾在一家抵押貸款公司工作,他們非常關心他們希望如何佈置他們的報告。降低到像素精度。不幸的是,GDI +不能很好地衡量文本。因此,您更好的選擇將使用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

我不能作出任何權利要求它是多麼準確。

+0

+1謝謝你看起來ni鈰,但在其他答案的情況下,我沒有看到如何從GDI +的答案中做場景2。您提供了有關如何測量和打印正常文本,如何測量和打印上標文本的答案,但沒有辦法一起測量和打印**和一起打印**(請參閱方案2的說明)。如果有一種方法我看不到,請提供簡單的代碼示例/方法鏈接/描述如何執行。 – drasto 2011-04-22 09:32:46

+0

我猜想文本的差異在於(超/副)腳本文本與正常文本大小不同。 GDI +爲您提供繪畫工具。你必須對請求進行解析並測量你的字符串,然後你可以在你想要的地方繪製它們。我的建議是,繪製第一組正常文本,然後是超級或下標文本,最後是下一組正常文本。這是我的觀點,這是任何其他應用程序會做的。但是這會給你對你的產品的最大控制。 – 2011-04-22 17:34:14