使用数据库PDF字符串初始化iText7 PdfReader时遇'Trailer Not Found'异常
核心问题:PDF字符串存储数据库后iText7解析失败(Trailer not found)
我需要将用户上传的IFormFile类型PDF文件内容以字符串(pdfAsString)形式存入数据库,当前存储代码如下:
string pdfAsString; using (var reader = new StreamReader(indexModel.UploadModel.File.OpenReadStream())) { pdfAsString = await reader.ReadToEndAsync(); // pdfAsString = ; // encoding function or lack thereof }
从数据库取出该字符串后,尝试初始化MemoryStream并以此创建PdfReader和PdfDocument时,触发了'Trailer not found'异常。已确认字符串中包含PDF的Trailer部分,且已将流位置设置到起始处。问题核心在于数据库取出的PDF内容格式异常,导致iText7无法正常解析除文件开头外的内容,期望能通过数据库存储的内容成功创建PdfDocument实例。
注1:直接使用
OpenReadStream()创建的流初始化PdfReader和PdfDocument可正常工作,但读取数据库时无法获取原IFormFile,此方法不适用。
注2:通过本地路径或FileStream加载PDF可正常工作,但不符合当前使用场景。
已尝试的解决方案
已尝试以下4种方案,但均未解决问题:
- 直接存储原始字符串并直接使用
- 将
\n、\t等特殊符号编码为ASCII十六进制 - 存储时用
HttpUtility.UrlEncode,读取时用UrlDecode - 存储时转Base64字符串,读取时用
FromBase64String解码
对应的读取代码如下:
// var pdfContent = databaseString; // 方案1 // var pdfContent = databaseString.EncodeSpecialCharacters(); // 方案2:编码特殊符号 // var pdfContent = HttpUtility.UrlDecode(databaseString); // 方案3:解码URL编码字符串 var pdfContent = Convert.FromBase64String(databaseString); // 方案4:Base64解码 using (var stream = new MemoryStream(pdfContent)) { PdfReader pdfReader = new PdfReader(stream).SetUnethicalReading(true); PdfWriter pdfWriter = new PdfWriter("new-file.pdf"); PdfDocument pdf = new PdfDocument(pdfReader, pdfWriter); // 异常触发处 :( // 业务逻辑... }
测试项目复现情况
在测试项目中,直接用formFile.OpenReadStream()初始化PdfReader可正常工作,但将流转为字符串再转回MemoryStream时触发相同异常,测试代码如下:
using (var stream = File.OpenRead("C:\\<path>\\<filename>.pdf")) { var formFile = new FormFile(stream, 0, stream.Length, null, "<filename>.pdf"); var reader = new StreamReader(formFile.OpenReadStream()); var pdfAsString = reader.ReadToEnd(); var pdfAsBytes = Encoding.UTF8.GetBytes(pdfAsString); using (var newStream = new MemoryStream(pdfAsBytes)) { newStream.Seek(0, SeekOrigin.Begin); var pdfReader = new PdfReader(newStream).SetUnethicalReading(true); var pdfWriter = new PdfWriter("Test-PDF-1.pdf"); PdfDocument pdf = new PdfDocument(pdfReader, pdfWriter); PdfAcroForm form = PdfAcroForm.GetAcroForm(pdf, true); IDictionary<string, PdfFormField> fields = form.GetFormFields(); foreach (var field in fields) { field.Value.SetValue(field.Key); } //form.FlattenFields(); pdf.Close(); } }
恳请提供可行的解决思路。
内容的提问来源于stack exchange,提问作者Comand94
相关产品推荐
相关产品推荐

