我错过了什么步骤或顺序错误导致此 PDF 写入失败?
What step am I missing or do I have in the wrong order that is causing this PDF writing to fail?
我有这段代码可以生成 PDF 文件,但它打不开,当我尝试时 Edge 告诉我,“无法打开 PDF。有什么东西阻止了这个 PDF 打开。 "
这是不知何故搞砸了的代码 up/haywire(删除了不相关和冗余的代码):
public static void GenerateAndEmailScheduleToChairmen(int year, int month)
{
. . .
try
{
using (var ms = new MemoryStream())
{
using (var doc = new Document(PageSize.A4.Rotate(), 25, 25, 25,
25))
{
using (var writer = PdfWriter.GetInstance(doc, ms))
{
doc.Open();
// Title
PdfPTable titleTable = new PdfPTable(1);
Paragraph title = new Paragraph(
$"CHAIRMEN'S SCHEDULE FOR
{AYttFMConstsAndUtils.GetMonthForInt(month)}, {year}");
title.Font.SetFamily("Verdana");
title.Font.Size = 16;
var titleCell = new PdfPCell();
titleCell.AddElement(title);
titleTable.AddCell(titleCell);
doc.Add(titleTable);
// Column Headings
PdfPTable tblHeadings = new PdfPTable(6)
{
WidthPercentage = 80,
SpacingBefore = 10f
};
float[] headingRowWidths = new float[] {180f, 180f,
180f, 180f, 100f, 180f};
tblHeadings.SetWidths(headingRowWidths);
tblHeadings.HorizontalAlignment = Element.ALIGN_LEFT;
Phrase phraseWeekBeginningHeading = new Phrase("Week
Beginning", courier11BoldYellow);
PdfPCell cellWeekBeginningHeading =
GetCellForBorderedTable(phraseWeekBeginningHeading,
Element.ALIGN_CENTER, BaseColor.BLUE);
tblHeadings.AddCell(cellWeekBeginningHeading);
. . .
// Main Contents
DateTime prevD8 =
humanFriendlyAssignmentVals[0].WeekOfAssignment.Date;
foreach (AssignmentStudentMashup asmRec in
humanFriendlyAssignmentVals)
{
// add a paragraph break when the week changes
PdfPTable tblRow;
if (asmRec.WeekOfAssignment.Date != prevD8)
{
tblRow = new PdfPTable(6)
{
WidthPercentage = 80,
SpacingBefore = 10f
};
headingRowWidths = new[] {180f, 180f, 180f,
180f, 100f, 180f};
tblRow.SetWidths(headingRowWidths);
tblRow.HorizontalAlignment = Element.ALIGN_LEFT;
// Add blank row
var phraseblankRow = new Phrase();
var cellBlankRow = new PdfPCell(phraseblankRow)
{BorderWidth = 0};
tblRow.AddCell(cellBlankRow);
}
prevD8 = asmRec.WeekOfAssignment;
tblRow = new PdfPTable(6)
{
WidthPercentage = 80,
SpacingBefore = 10f
};
headingRowWidths = new[] {180f, 180f, 180f, 180f,
100f, 180f};
tblRow.SetWidths(headingRowWidths);
tblRow.HorizontalAlignment = Element.ALIGN_LEFT;
var phraseWeekBeginning = new
Phrase(asmRec.WeekOfAssignment.ToLongDateString(),
courier11BoldYellow);
var cellWeekBeginning =
GetCellForBorderedTable(phraseWeekBeginning,
Element.ALIGN_CENTER, BaseColor.BLUE);
tblRow.AddCell(cellWeekBeginning);
. . .
doc.Add(tblHeadings);
} // writer
var bytes = ms.ToArray();
String PDFFileName =
$"ChairmensCounselInfo_{DateTime.Now.ToShortTimeString()}.pdf";
PDFFileName = PDFFileName.Replace(":", "_");
var chairmansPDFFile = $"C:\AYttFMApp\{PDFFileName}";
File.WriteAllBytes(chairmansPDFFile, bytes);
MessageBox.Show($"{PDFFileName} written");
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(${ex.Message});
}
}
我看到 "file written" messagebox.show,但随后出现“无法访问已关闭的流”
更新
我现在正在创建 MemoryStream,但没有使用关闭,并在编写之前关闭了文档,但我仍然收到一条消息,指出无法打开 PDF 文件(尽管它确实有一些内容 (2KB))。
我认为 "writer" 至少是部分问题,因为没有它,PDF 是 0KB,但是有了它,"writer" 是灰色的,好像它没有被使用.现在这是我的代码(只有上面提到的那些差异):
try
{
var ms = new MemoryStream();
using (var doc = new Document(PageSize.A4.Rotate(), 25, 25, 25, 25))
{
using (var writer = PdfWriter.GetInstance(doc, ms))
{
doc.Open();
// Title
PdfPTable titleTable = new PdfPTable(1);
Paragraph title = new Paragraph(
$"CHAIRMEN'S SCHEDULE FOR
{AYttFMConstsAndUtils.GetMonthForInt(month)}, {year}");
title.Font.SetFamily("Verdana");
title.Font.Size = 16;
var titleCell = new PdfPCell();
titleCell.AddElement(title);
titleTable.AddCell(titleCell);
doc.Add(titleTable);
// Column Headings
PdfPTable tblHeadings = new PdfPTable(6)
{
WidthPercentage = 80,
SpacingBefore = 10f
};
float[] headingRowWidths = new float[] { 180f, 180f, 180f,
180f, 100f, 180f };
tblHeadings.SetWidths(headingRowWidths);
tblHeadings.HorizontalAlignment = Element.ALIGN_LEFT;
Phrase phraseWeekBeginningHeading = new Phrase("Week
Beginning", courier11BoldYellow);
PdfPCell cellWeekBeginningHeading =
GetCellForBorderedTable(phraseWeekBeginningHeading,
Element.ALIGN_CENTER, BaseColor.BLUE);
tblHeadings.AddCell(cellWeekBeginningHeading);
. . .
// Main Contents
DateTime prevD8 =
humanFriendlyAssignmentVals[0].WeekOfAssignment.Date;
foreach (AssignmentStudentMashup asmRec in
humanFriendlyAssignmentVals)
{
// add a paragraph break when the week changes
PdfPTable tblRow;
if (asmRec.WeekOfAssignment.Date != prevD8)
{
tblRow = new PdfPTable(6)
{
WidthPercentage = 80,
SpacingBefore = 10f
};
headingRowWidths = new[] { 180f, 180f, 180f, 180f,
100f, 180f };
tblRow.SetWidths(headingRowWidths);
tblRow.HorizontalAlignment = Element.ALIGN_LEFT;
// Add blank row
var phraseblankRow = new Phrase();
var cellBlankRow = new PdfPCell(phraseblankRow)
{ BorderWidth = 0 };
tblRow.AddCell(cellBlankRow);
}
prevD8 = asmRec.WeekOfAssignment;
tblRow = new PdfPTable(6)
{
WidthPercentage = 80,
SpacingBefore = 10f
};
headingRowWidths = new[] { 180f, 180f, 180f, 180f, 100f,
180f };
tblRow.SetWidths(headingRowWidths);
tblRow.HorizontalAlignment = Element.ALIGN_LEFT;
var phraseWeekBeginning = new
Phrase(asmRec.WeekOfAssignment.ToLongDateString(),
courier11BoldYellow);
var cellWeekBeginning =
GetCellForBorderedTable(phraseWeekBeginning,
Element.ALIGN_CENTER, BaseColor.BLUE);
tblRow.AddCell(cellWeekBeginning);
. . .
var phraseCounselPoint = new
Phrase(asmRec.CounselPointStr, courier11BoldYellow);
var cellCounselPoint
GetCellForBorderedTable(phraseCounselPoint, Element.ALIGN_CENTER,
BaseColor.BLUE);
tblRow.AddCell(cellCounselPoint);
doc.Add(tblHeadings);
} // writer
var bytes = ms.ToArray();
String PDFFileName =
$"ChairmensInfo_{DateTime.Now.ToShortTimeString()}.pdf";
PDFFileName = PDFFileName.Replace(":", "_");
var chairmansPDFFile = $"C:\AYttFMApp\{PDFFileName}";
doc.Close();
File.WriteAllBytes(chairmansPDFFile, bytes);
MessageBox.Show($"{PDFFileName} written");
}
}
}
catch (DocumentException dex)
{
MessageBox.Show($"DocumentException: {dex.Message}");
throw;
}
catch (IOException ioex)
{
MessageBox.Show($"IOException: {ioex.Message}");
throw;
}
catch (Exception ex)
{
MessageBox.Show($"General Exception: {ex.Message}");
}
我没有看到任何异常消息。
更新 2
好的,这就是工作所需:
var ms = new MemoryStream();
using (var doc = new Document(PageSize.A4.Rotate(), 25, 25, 25, 25))
{
PdfWriter.GetInstance(doc, ms);
doc.Open();
. . . // contents added to the file, same as before
doc.Add(tblHeadings);
} // using doc
var bytes = ms.ToArray();
String PDFFileName = $"ChairmensCounselInfo_{DateTime.Now.ToShortTimeString()}.pdf";
PDFFileName = PDFFileName.Replace(":", "_");
var chairmansPDFFile = $"C:\AYttFMApp\{PDFFileName}";
File.WriteAllBytes(chairmansPDFFile, bytes);
MessageBox.Show($"{PDFFileName} written");
您正在使用 MemoryStream
创建一个 byte
数组 ,然后 Document
关闭。这会导致 PDF 不完整。
在创建 Document
的 using
的末尾,PDF 已完成(例如,编写了基本的交叉引用 table),但到那时,您已经使用不完整的流写入了PDF文件。
如何解决这个问题?
不要使用 using
创建 MemoryStream
。等到 Document
关闭,然后再将 MemoryStream
的字节写入 PDF 文件。
更新:
您在更新中没有正确遵循我的建议。你有这样的东西:
var ms = new MemoryStream();
using (var doc = new Document(PageSize.A4.Rotate(), 25, 25, 25, 25))
{
using (var writer = PdfWriter.GetInstance(doc, ms))
{
doc.Open();
// adding content
var bytes = ms.ToArray();
doc.Close();
// write bytes to a file.
}
}
正如我之前解释的,这是错误的。您正在将不完整的 PDF 的内容写入名为 bytes
的字节数组。该 PDF 已损坏,因为它没有交叉引用 table。交叉引用 table 仅在您 Close()
文档时创建,无论是显式还是隐式。您现在 Close()
在创建 bytes
数组后显式地创建文档。太晚了。
你需要这样的东西:
var ms = new MemoryStream();
using (var doc = new Document(PageSize.A4.Rotate(), 25, 25, 25, 25))
{
var writer = PdfWriter.GetInstance(doc, ms));
doc.Open();
// adding content
}
var bytes = ms.ToArray();
// write bytes to a file
如果你不需要writer
,你甚至可以这样做:
var ms = new MemoryStream();
using (var doc = new Document(PageSize.A4.Rotate(), 25, 25, 25, 25))
{
PdfWriter.GetInstance(doc, ms));
doc.Open();
// adding content
}
var bytes = ms.ToArray();
// write bytes to a file
只需确保创建完整的 PDF:
- 不要在
writer
Document
有机会关闭之前关闭。
- 不要使用
ms
在 Document
有机会关闭之前。
我有这段代码可以生成 PDF 文件,但它打不开,当我尝试时 Edge 告诉我,“无法打开 PDF。有什么东西阻止了这个 PDF 打开。 "
这是不知何故搞砸了的代码 up/haywire(删除了不相关和冗余的代码):
public static void GenerateAndEmailScheduleToChairmen(int year, int month)
{
. . .
try
{
using (var ms = new MemoryStream())
{
using (var doc = new Document(PageSize.A4.Rotate(), 25, 25, 25,
25))
{
using (var writer = PdfWriter.GetInstance(doc, ms))
{
doc.Open();
// Title
PdfPTable titleTable = new PdfPTable(1);
Paragraph title = new Paragraph(
$"CHAIRMEN'S SCHEDULE FOR
{AYttFMConstsAndUtils.GetMonthForInt(month)}, {year}");
title.Font.SetFamily("Verdana");
title.Font.Size = 16;
var titleCell = new PdfPCell();
titleCell.AddElement(title);
titleTable.AddCell(titleCell);
doc.Add(titleTable);
// Column Headings
PdfPTable tblHeadings = new PdfPTable(6)
{
WidthPercentage = 80,
SpacingBefore = 10f
};
float[] headingRowWidths = new float[] {180f, 180f,
180f, 180f, 100f, 180f};
tblHeadings.SetWidths(headingRowWidths);
tblHeadings.HorizontalAlignment = Element.ALIGN_LEFT;
Phrase phraseWeekBeginningHeading = new Phrase("Week
Beginning", courier11BoldYellow);
PdfPCell cellWeekBeginningHeading =
GetCellForBorderedTable(phraseWeekBeginningHeading,
Element.ALIGN_CENTER, BaseColor.BLUE);
tblHeadings.AddCell(cellWeekBeginningHeading);
. . .
// Main Contents
DateTime prevD8 =
humanFriendlyAssignmentVals[0].WeekOfAssignment.Date;
foreach (AssignmentStudentMashup asmRec in
humanFriendlyAssignmentVals)
{
// add a paragraph break when the week changes
PdfPTable tblRow;
if (asmRec.WeekOfAssignment.Date != prevD8)
{
tblRow = new PdfPTable(6)
{
WidthPercentage = 80,
SpacingBefore = 10f
};
headingRowWidths = new[] {180f, 180f, 180f,
180f, 100f, 180f};
tblRow.SetWidths(headingRowWidths);
tblRow.HorizontalAlignment = Element.ALIGN_LEFT;
// Add blank row
var phraseblankRow = new Phrase();
var cellBlankRow = new PdfPCell(phraseblankRow)
{BorderWidth = 0};
tblRow.AddCell(cellBlankRow);
}
prevD8 = asmRec.WeekOfAssignment;
tblRow = new PdfPTable(6)
{
WidthPercentage = 80,
SpacingBefore = 10f
};
headingRowWidths = new[] {180f, 180f, 180f, 180f,
100f, 180f};
tblRow.SetWidths(headingRowWidths);
tblRow.HorizontalAlignment = Element.ALIGN_LEFT;
var phraseWeekBeginning = new
Phrase(asmRec.WeekOfAssignment.ToLongDateString(),
courier11BoldYellow);
var cellWeekBeginning =
GetCellForBorderedTable(phraseWeekBeginning,
Element.ALIGN_CENTER, BaseColor.BLUE);
tblRow.AddCell(cellWeekBeginning);
. . .
doc.Add(tblHeadings);
} // writer
var bytes = ms.ToArray();
String PDFFileName =
$"ChairmensCounselInfo_{DateTime.Now.ToShortTimeString()}.pdf";
PDFFileName = PDFFileName.Replace(":", "_");
var chairmansPDFFile = $"C:\AYttFMApp\{PDFFileName}";
File.WriteAllBytes(chairmansPDFFile, bytes);
MessageBox.Show($"{PDFFileName} written");
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(${ex.Message});
}
}
我看到 "file written" messagebox.show,但随后出现“无法访问已关闭的流”
更新
我现在正在创建 MemoryStream,但没有使用关闭,并在编写之前关闭了文档,但我仍然收到一条消息,指出无法打开 PDF 文件(尽管它确实有一些内容 (2KB))。
我认为 "writer" 至少是部分问题,因为没有它,PDF 是 0KB,但是有了它,"writer" 是灰色的,好像它没有被使用.现在这是我的代码(只有上面提到的那些差异):
try
{
var ms = new MemoryStream();
using (var doc = new Document(PageSize.A4.Rotate(), 25, 25, 25, 25))
{
using (var writer = PdfWriter.GetInstance(doc, ms))
{
doc.Open();
// Title
PdfPTable titleTable = new PdfPTable(1);
Paragraph title = new Paragraph(
$"CHAIRMEN'S SCHEDULE FOR
{AYttFMConstsAndUtils.GetMonthForInt(month)}, {year}");
title.Font.SetFamily("Verdana");
title.Font.Size = 16;
var titleCell = new PdfPCell();
titleCell.AddElement(title);
titleTable.AddCell(titleCell);
doc.Add(titleTable);
// Column Headings
PdfPTable tblHeadings = new PdfPTable(6)
{
WidthPercentage = 80,
SpacingBefore = 10f
};
float[] headingRowWidths = new float[] { 180f, 180f, 180f,
180f, 100f, 180f };
tblHeadings.SetWidths(headingRowWidths);
tblHeadings.HorizontalAlignment = Element.ALIGN_LEFT;
Phrase phraseWeekBeginningHeading = new Phrase("Week
Beginning", courier11BoldYellow);
PdfPCell cellWeekBeginningHeading =
GetCellForBorderedTable(phraseWeekBeginningHeading,
Element.ALIGN_CENTER, BaseColor.BLUE);
tblHeadings.AddCell(cellWeekBeginningHeading);
. . .
// Main Contents
DateTime prevD8 =
humanFriendlyAssignmentVals[0].WeekOfAssignment.Date;
foreach (AssignmentStudentMashup asmRec in
humanFriendlyAssignmentVals)
{
// add a paragraph break when the week changes
PdfPTable tblRow;
if (asmRec.WeekOfAssignment.Date != prevD8)
{
tblRow = new PdfPTable(6)
{
WidthPercentage = 80,
SpacingBefore = 10f
};
headingRowWidths = new[] { 180f, 180f, 180f, 180f,
100f, 180f };
tblRow.SetWidths(headingRowWidths);
tblRow.HorizontalAlignment = Element.ALIGN_LEFT;
// Add blank row
var phraseblankRow = new Phrase();
var cellBlankRow = new PdfPCell(phraseblankRow)
{ BorderWidth = 0 };
tblRow.AddCell(cellBlankRow);
}
prevD8 = asmRec.WeekOfAssignment;
tblRow = new PdfPTable(6)
{
WidthPercentage = 80,
SpacingBefore = 10f
};
headingRowWidths = new[] { 180f, 180f, 180f, 180f, 100f,
180f };
tblRow.SetWidths(headingRowWidths);
tblRow.HorizontalAlignment = Element.ALIGN_LEFT;
var phraseWeekBeginning = new
Phrase(asmRec.WeekOfAssignment.ToLongDateString(),
courier11BoldYellow);
var cellWeekBeginning =
GetCellForBorderedTable(phraseWeekBeginning,
Element.ALIGN_CENTER, BaseColor.BLUE);
tblRow.AddCell(cellWeekBeginning);
. . .
var phraseCounselPoint = new
Phrase(asmRec.CounselPointStr, courier11BoldYellow);
var cellCounselPoint
GetCellForBorderedTable(phraseCounselPoint, Element.ALIGN_CENTER,
BaseColor.BLUE);
tblRow.AddCell(cellCounselPoint);
doc.Add(tblHeadings);
} // writer
var bytes = ms.ToArray();
String PDFFileName =
$"ChairmensInfo_{DateTime.Now.ToShortTimeString()}.pdf";
PDFFileName = PDFFileName.Replace(":", "_");
var chairmansPDFFile = $"C:\AYttFMApp\{PDFFileName}";
doc.Close();
File.WriteAllBytes(chairmansPDFFile, bytes);
MessageBox.Show($"{PDFFileName} written");
}
}
}
catch (DocumentException dex)
{
MessageBox.Show($"DocumentException: {dex.Message}");
throw;
}
catch (IOException ioex)
{
MessageBox.Show($"IOException: {ioex.Message}");
throw;
}
catch (Exception ex)
{
MessageBox.Show($"General Exception: {ex.Message}");
}
我没有看到任何异常消息。
更新 2
好的,这就是工作所需:
var ms = new MemoryStream();
using (var doc = new Document(PageSize.A4.Rotate(), 25, 25, 25, 25))
{
PdfWriter.GetInstance(doc, ms);
doc.Open();
. . . // contents added to the file, same as before
doc.Add(tblHeadings);
} // using doc
var bytes = ms.ToArray();
String PDFFileName = $"ChairmensCounselInfo_{DateTime.Now.ToShortTimeString()}.pdf";
PDFFileName = PDFFileName.Replace(":", "_");
var chairmansPDFFile = $"C:\AYttFMApp\{PDFFileName}";
File.WriteAllBytes(chairmansPDFFile, bytes);
MessageBox.Show($"{PDFFileName} written");
您正在使用 MemoryStream
创建一个 byte
数组 ,然后 Document
关闭。这会导致 PDF 不完整。
在创建 Document
的 using
的末尾,PDF 已完成(例如,编写了基本的交叉引用 table),但到那时,您已经使用不完整的流写入了PDF文件。
如何解决这个问题?
不要使用 using
创建 MemoryStream
。等到 Document
关闭,然后再将 MemoryStream
的字节写入 PDF 文件。
更新:
您在更新中没有正确遵循我的建议。你有这样的东西:
var ms = new MemoryStream();
using (var doc = new Document(PageSize.A4.Rotate(), 25, 25, 25, 25))
{
using (var writer = PdfWriter.GetInstance(doc, ms))
{
doc.Open();
// adding content
var bytes = ms.ToArray();
doc.Close();
// write bytes to a file.
}
}
正如我之前解释的,这是错误的。您正在将不完整的 PDF 的内容写入名为 bytes
的字节数组。该 PDF 已损坏,因为它没有交叉引用 table。交叉引用 table 仅在您 Close()
文档时创建,无论是显式还是隐式。您现在 Close()
在创建 bytes
数组后显式地创建文档。太晚了。
你需要这样的东西:
var ms = new MemoryStream();
using (var doc = new Document(PageSize.A4.Rotate(), 25, 25, 25, 25))
{
var writer = PdfWriter.GetInstance(doc, ms));
doc.Open();
// adding content
}
var bytes = ms.ToArray();
// write bytes to a file
如果你不需要writer
,你甚至可以这样做:
var ms = new MemoryStream();
using (var doc = new Document(PageSize.A4.Rotate(), 25, 25, 25, 25))
{
PdfWriter.GetInstance(doc, ms));
doc.Open();
// adding content
}
var bytes = ms.ToArray();
// write bytes to a file
只需确保创建完整的 PDF:
- 不要在
writer
Document
有机会关闭之前关闭。 - 不要使用
ms
在Document
有机会关闭之前。