Skip to main content
 首页 » 编程设计

c#之如何在合并 PDF 后解锁文件以进行删除

2024年05月06日41sxdcgaq8080

更新

查看完整解决方案的答案。


我现在更新了代码,最后几行是:

       reader.Close(); 
        f++; 
        if (f >= orderedList.Count) continue; 
        reader = new PdfReader(targetFolder + orderedList[f]); 
        // we retrieve the total number of pages 
        n = reader.NumberOfPages; 
        pdfNewPageFlag = true; 
       reader.Close(); 
    } 
} 

并且文档已成功完成,但最终的 PDF 已损坏(我假设是因为它没有正确关闭)


作为 Word 到 PDF 转换和合并过程的一部分,我正在运行以下方法将所有 PDF 合并为 1 个 super PDF(使用 iTextSharp.text.pdf):

    public void Pdfs(string targetPdf, List<string> orderedList, string targetFolder, string spSite) 
    { 
        var f = 0; 
        // we create a reader for a certain document 
        var reader = new PdfReader(targetFolder + orderedList[f]); 
        // we retrieve the total number of pages 
        var n = reader.NumberOfPages; 
        // step 1: creation of a document-object 
        var document = new iTextSharp.text.Document(reader.GetPageSizeWithRotation(1)); 
         
        // step 2: we create a writer that listens to the document 
        var writer = PdfWriter.GetInstance(document, new FileStream(targetPdf, FileMode.Create)); 
        // step 3: we open the document 
        document.Open(); 
        var cb = writer.DirectContent; 
        PdfImportedPage page; 
        int rotation; 
        // step 4: we add content 
        var pdfPageName = 0; 
        var pdfNewPageFlag = true; 
        while (f < orderedList.Count) 
        { 
            var i = 0; 
            while (i < n) 
            { 
                i++; 
                document.SetPageSize(reader.GetPageSizeWithRotation(i)); 
                document.NewPage(); 
                if (pdfNewPageFlag) 
                { 
                    var chapter = new iTextSharp.text.Chapter(orderedList[pdfPageName], pdfPageName + 1); 
                    document.Add(chapter); 
                    pdfNewPageFlag = false; 
                    pdfPageName++; 
                } 
 
                page = writer.GetImportedPage(reader, i); 
                rotation = reader.GetPageRotation(i); 
 
                if (rotation == 90 || rotation == 270) 
                { 
                    cb.AddTemplate(page, 0, -1f, 1f, 0, 0, reader.GetPageSizeWithRotation(i).Height); 
                } 
                else 
                { 
                    cb.AddTemplate(page, 1f, 0, 0, 1f, 0, 0); 
                } 
            } 
            f++; 
            if (f >= orderedList.Count) continue; 
            reader = new PdfReader(targetFolder + orderedList[f]); 
            // we retrieve the total number of pages 
            n = reader.NumberOfPages; 
            pdfNewPageFlag = true; 
        } 
 
        // step 5: we close the document 
        document.Close(); 
    } 

此方法还会在每个原始文档的开头创建一个书签。文件全部合并后,我将调用此方法删除文件:

    private static void DeletePdfs() 
    { 
        // Delete the files 
        foreach (var file in orderedListPdfFileNames) 
        { 
            var newFileName = tempfolder + file; 
            File.Delete(newFileName); 
        } 
    } 

但是当尝试实际删除文件时,我看到了这个异常:

An unhandled exception of type 'System.IO.IOException' occurred in mscorlib.dll

Additional information: The process cannot access the file '\file\IT\SK\test\HrDocs\Cover.pdf' because it is being used by another process.

在 PDFs 方法中,我尝试在 之前和之后调用 writer.Close() 和 reader.Close() >document.Close(),但随后我收到消息 Cannot close a document which is already closed。

有人能帮我解决这个问题或给我指明正确的方向吗?我似乎无法弄清楚合并过程的哪一部分正在锁定文件!

请您参考如下方法:

这只是没有在正确的地方关闭读者的情况。

正如 mkl 在评论中提到的,如果 document.Close() 在关闭阅读器后失败,那么我需要在之后关闭阅读器。

在下面的修改中,我在创建后将每个读者添加到列表中,最后它们都关闭了:

    public void Pdfs(string targetPdf, List<string> orderedList, string targetFolder, string spSite) 
    { 
        var readerlist = new List<PdfReader>(); 
 
        var f = 0; 
        // we create a reader for a certain document 
        var reader = new PdfReader(targetFolder + orderedList[f]); 
        readerlist.Add(reader); 
 
        // we retrieve the total number of pages 
        var n = reader.NumberOfPages; 
        // step 1: creation of a document-object 
        var document = new iTextSharp.text.Document(reader.GetPageSizeWithRotation(1)); 
 
        // step 2: we create a writer that listens to the document 
        var writer = PdfWriter.GetInstance(document, new FileStream(targetPdf, FileMode.Create)); 
        // step 3: we open the document 
        document.Open(); 
        var cb = writer.DirectContent; 
        PdfImportedPage page; 
        int rotation; 
        // step 4: we add content 
        var pdfPageName = 0; 
        var pdfNewPageFlag = true; 
        while (f < orderedList.Count) 
        { 
            var i = 0; 
            while (i < n) 
            { 
                i++; 
                document.SetPageSize(reader.GetPageSizeWithRotation(i)); 
                document.NewPage(); 
                if (pdfNewPageFlag) 
                { 
                    var chapter = new iTextSharp.text.Chapter(orderedList[pdfPageName], pdfPageName + 1); 
                    document.Add(chapter); 
                    pdfNewPageFlag = false; 
                    pdfPageName++; 
                } 
 
                page = writer.GetImportedPage(reader, i); 
                rotation = reader.GetPageRotation(i); 
 
                if (rotation == 90 || rotation == 270) 
                { 
                    cb.AddTemplate(page, 0, -1f, 1f, 0, 0, reader.GetPageSizeWithRotation(i).Height); 
                } 
                else 
                { 
                    cb.AddTemplate(page, 1f, 0, 0, 1f, 0, 0); 
                } 
            } 
 
            f++; 
            if (f >= orderedList.Count) continue; 
            reader = new PdfReader(targetFolder + orderedList[f]); 
            readerlist.Add(reader); 
 
            // we retrieve the total number of pages 
            n = reader.NumberOfPages; 
            pdfNewPageFlag = true; 
        } 
 
        // step 5: we close the document 
        document.Close(); 
 
        foreach (var rdr in readerlist) 
        { 
            rdr.Close(); 
        } 
    }