如何检测pdf文档是不是有损坏

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何检测pdf文档是不是有损坏相关的知识,希望对你有一定的参考价值。

参考技术A 用pdf文件修复工具,如:advanced
pdf
repair
v1.0。它使用高级技术扫描被损坏的
acrobat
pdf
文件,并尽最大可能恢复你的文件,使你能够最大程度的减少文件破坏后所带来的损失。当前
apdfr
支持恢复所有版本的
adobe
pdf
文档,它与
windows
资源管理器整合,支持拖放操作和命令行参数,使你能更方便、快速的修复
pdf
文件。

iTextSharp 正在生成损坏的 PDF

【中文标题】iTextSharp 正在生成损坏的 PDF【英文标题】:iTextSharp is producing a corrupt PDF 【发布时间】:2011-09-16 11:31:10 【问题描述】:

下面的代码 sn-p 返回一个损坏的 PDF 文档,但是如果我返回 mergeDocument,它总是返回一个有效的 PDF。 mergeDocument 是基于我使用 Word 创建的 PDF 文件,而完成的文档是完全以编程方式生成的。代码“有效”,因为它不会引发异常。为什么 iTextSharp 创建损坏的 PDF?

byte[] completedDocument = null;            
using (MemoryStream streamCompleted = new MemoryStream())

    using (Document document = new Document())
                        
        PdfCopy copy = new PdfCopy(document, streamCompleted);
        document.Open();
        copy.Open();                    

        foreach (var item in eventItems)
        
            byte[] mergedDocument = null;
            PdfReader reader = new PdfReader(pdfTemplates[item.DataTokens[NotifyTokenType.OrganisationID]]);
            using (MemoryStream streamTemplate = new MemoryStream())
            
                using (PdfStamper stamper = new PdfStamper(reader, streamTemplate))
                
                    foreach (var token in item.DataTokens)
                    
                        if (stamper.AcroFields.Fields.Any(fld => fld.Key == token.Key.ToString()))
                        
                            stamper.AcroFields.SetField(token.Key.ToString(), token.Value);
                        
                    
                    stamper.FormFlattening = true;
                    stamper.Writer.CloseStream = false;
                

                mergedDocument = new byte[streamTemplate.Length];
                streamTemplate.Position = 0;
                streamTemplate.Read(mergedDocument, 0, (int)streamTemplate.Length);
            
            reader = new PdfReader(mergedDocument);

            for (int i = 1; i <= reader.NumberOfPages; i++)
            
                document.SetPageSize(PageSize.A4);
                copy.AddPage(copy.GetImportedPage(reader, i));
            
        
        completedDocument = new byte[streamCompleted.Length];
        streamCompleted.Position = 0;
        streamCompleted.Read(completedDocument, 0, (int)streamCompleted.Length);
                    

return completedDocument;

【问题讨论】:

【参考方案1】:

您需要关闭 documentcopy 对象以刷新 PDF 写入缓冲区。但是,这在尝试将流读入数组时会导致一些问题。解决方法是使用MemoryStreamToArray() 方法,它仍然适用于封闭的流。我所做的更改上有 cmets。

        byte[] completedDocument = null;
        using (MemoryStream streamCompleted = new MemoryStream())
        
            using (Document document = new Document())
            
                PdfCopy copy = new PdfCopy(document, streamCompleted);
                document.Open();
                copy.Open();

                foreach (var item in eventItems)
                
                    byte[] mergedDocument = null;
                    PdfReader reader = new PdfReader(pdfTemplates[item.DataTokens[NotifyTokenType.OrganisationID]]);
                    using (MemoryStream streamTemplate = new MemoryStream())
                    
                        using (PdfStamper stamper = new PdfStamper(reader, streamTemplate))
                        
                            foreach (var token in item.DataTokens)
                            
                                if (stamper.AcroFields.Fields.Any(fld => fld.Key == token.Key.ToString()))
                                
                                    stamper.AcroFields.SetField(token.Key.ToString(), token.Value);
                                
                            
                            stamper.FormFlattening = true;
                            stamper.Writer.CloseStream = false;
                        
                        //Copy the stream's bytes
                        mergedDocument = streamTemplate.ToArray();
                    
                    reader = new PdfReader(mergedDocument);

                    for (int i = 1; i <= reader.NumberOfPages; i++)
                    
                        document.SetPageSize(PageSize.A4);
                        copy.AddPage(copy.GetImportedPage(reader, i));
                    
                    //Close the document and the copy
                    document.Close();
                    copy.Close();
                
                //ToArray() can operate on closed streams
                completedDocument = streamCompleted.ToArray();
            
        
        return completedDocument;

【讨论】:

如果可以的话,我会投票 1000 次。我在将图像和 pdf 合并为一个 pdf 文档时遇到了困难,这有助于阐明正确的过程。 谢谢,将内存流放入数组解决了我取回空 PDF 文件的问题!【参考方案2】:

在将 html 转换为 pdf 时,还要确保您的 html 不包含 hr 标签

hdnEditorText.Value.Replace("\"", "'").Replace("<hr />", "").Replace("<hr/>", "")

【讨论】:

以上是关于如何检测pdf文档是不是有损坏的主要内容,如果未能解决你的问题,请参考以下文章

怎么检测PDF文件是不是损坏

iText pdf完整性检查

怎么样快捷判断WORD\EXCEL\PDF\图片等文件,是不是已经损坏,或者判断文件是不是完好。

Java IText7 PDF 签名问题 - 文档自签名后已被更改或损坏

如何在 iPhone SDK 中检测 PDF 文档的方向

PDF文件损坏,将内存流移动到文件流时无法修复