【发布时间】:2013-08-20 12:48:43
【问题描述】:
我在使用 ITextSharp 创建一些推送到 MVC 浏览器应用程序的表和图像时遇到问题。我想我已经把它缩小到使用 WriteRowsSelected 添加表的范围内。
这是我的代码:
PDFEngine.cs
private byte[] BuildDocument(MemoryStream documentStream, IEnumerable<CustomPdfData> documents, bool addVoid, float defaultMagnification)
{
using (var stream = new MemoryStream())
{
var finishedDocument = new Document(new Rectangle(612f, 792f));
var writer = PdfWriter.GetInstance(finishedDocument, stream);
writer.ViewerPreferences = PdfWriter.HideWindowUI;
writer.ViewerPreferences = PdfWriter.HideMenubar;
// Open the Document for writing
finishedDocument.Open();
var zoomer = PdfAction.GotoLocalPage(1, new PdfDestination(PdfDestination.XYZ, -1, -1, defaultMagnification), writer);
writer.SetOpenAction(zoomer);
foreach (var document in documents)
{
if (document.IsNewPage)
{
finishedDocument.NewPage();
}
var results = TableEngine.BuildDocument(document);
// Build Canvas for Table
//PdfContentByte canvas = writer.DirectContent;
//canvas.SetTextMatrix(50, 50);
// Add each table to the canvas at specified coordinates
for (int tableCounter = 0; tableCounter < results.ITextTables.Count; tableCounter++)
{
PdfContentByte canvas = writer.DirectContent;
canvas.SetTextMatrix(50, 50);
var xAxis = results.PdfTables[tableCounter].XPosition;
var yAxis = results.PdfTables[tableCounter].YPosition;
results.ITextTables[tableCounter].WriteSelectedRows(0, results.PdfTables[tableCounter].ColumnSize, xAxis, yAxis, writer.DirectContent);
}
}
finishedDocument.Close();
documentStream.Close();
return stream.ToArray();
}
CheckBuilder.cs
/// <summary>
/// Used to create the fake checks needed for printing to a client
/// </summary>
/// <param name="checks">Checks to push to Builder</param>
/// <returns></returns>
public byte[] GetFakeChecks(List<HandsCheck> checks)
{
var doc = BuildCheck(checks, true, true);
return CreatePdf(doc, 0.5f, false);
}
DisplayChecks.cshtml
<object id="WebBrowser1" width="615" height="790" data= "@Url.Action("GetPdfData")" type="application/pdf" />
HomeController.cs
public FileContentResult GetPdfData()
{
int numberofChecks = int.Parse(Workspace.Get<string>("numberofChecks"));
var pdfCreator = new CheckBuilder();
var checks = GetAllChecks();
var newList = new List<Check>();
for (int counter = 0; counter < numberofChecks; counter++)
{
newList.Add(checks[counter]);
}
var rawData = pdfCreator.GetFakeChecks(newList);
return File(rawData, "application/pdf");
return null;
}
奇怪的是,它似乎只在我添加超过 1 表时才会发生。有谁知道每张画布是否有任何限制?有谁知道进一步调试可能导致此问题的任何方法?
【问题讨论】:
-
除了
Stream对象的传递之外,没有什么能引起我的注意。我还没有找到这样做的充分理由,但我看到了很多不这样做的理由。您能否尝试重构为仅使用内部MemoryStream并使用MS.ToArray()返回原始字节数组。这也将使您不必担心记住在方法之外关闭流以及调用错误的流方法,例如GetBuffer。 -
感谢@Chris 的回复。我更新了上面的代码以包含您推荐的重构。我想我按照您的要求做了,但我仍然收到错误消息。奇怪的是,PDF 总是正确显示。我还包含了 HTML 和控制器代码。此外,似乎如果我什至添加第二个表,它会引发相同的错误。我可能需要为多个 WriteSelectedRows 做些什么吗?
-
另外,如果我在每个 WriteRowsSelected 上添加一个 Newpage 调用,它没有问题,显然这不是预期的效果,但我认为这可能有助于解决这个奇怪的问题
-
接下来我会尝试几件事。首先,将实际字节写入服务器磁盘,然后将该文件与发送到客户端的二进制文件进行比较。也许 MVC 正在发送一些额外的字节(例如,如果您没有关闭连接)。如果可行,则删除您的特定于域的逻辑并编写一堆表。画布中的表格数量没有限制。实际上,从 PDF 的角度来看,没有“表格”这样的东西,它只是在某些坐标处绘制的文本,碰巧也在附近。
-
谢谢克里斯,下面的答案就是这样,但退后一步,一步一步尝试是个好主意。
标签: c# .net plugins itextsharp adobe-reader