none
iTextSharp - los archivos se quedan abiertos! Mensaje están siendo utilizados por otro usuario RRS feed

  • Pregunta

  • Buenos días,

    He creado un pequeño código donde creo un pdf en el que se combinan otros pdfs existentes. no tengo problema para abrir el nuevo PDF creado, pero si intento abrir uno de los que me han servido para crear el nuevo, entonces me da error, porque me dice que está siendo utilizado.

    El número de documentos a combinar es variable y sus rutas las almaceno en un array. Mi código es el siguiente:

    Public Sub CreaCombinaciónPDF()
            Try
                'El nuevo archivo
                Dim pdfDoc As Document = New Document(PageSize.LETTER)
                'Para poder grabar el documento en disco
                Dim memo As MemoryStream = New MemoryStream
                Dim PdfW As PdfWriter = PdfWriter.GetInstance(pdfDoc,
                                New FileStream(sAtexDirec & "\Comp\AnexoPDF_" & sAtex & ".pdf", FileMode.Create))
                PdfW.AddViewerPreference(PdfName.PICKTRAYBYPDFSIZE, PdfBoolean.PDFTRUE)
                'Atributos del nuevo PDF
                pdfDoc.AddAuthor("ATEXPRESS")
                pdfDoc.AddTitle(sAtex)
                pdfDoc.AddCreator(MiEntidad.GetCódigoEnt)
                pdfDoc.AddCreationDate()
                'Abrimos el documento
                pdfDoc.Open()
                '
                'Archivos a insertar
                For iArch = 1 To UBound(ArrayComp)
                    Dim pdfR As PdfReader = New PdfReader(sAtexDirec & "\Comp\" & ArrayComp(iArch))
                    Dim cb As PdfContentByte = PdfW.DirectContent
                    For iPage As Integer = 1 To NumPages
                        pdfDoc.SetPageSize(pdfR.GetPageSizeWithRotation(iPage))
                        pdfDoc.NewPage()
                        Dim ImportPage As PdfImportedPage = PdfW.GetImportedPage(pdfR, iPage)
                        'Página rotada
                        Dim iRotation As Integer = pdfR.GetPageRotation(iPage)
                        If (iRotation = 90) Or (iRotation = 270) Then
                            cb.AddTemplate(ImportPage, 0, -1.0F, 1.0F, 0, 0, pdfR.GetPageSizeWithRotation(iPage).Height)
                        Else
                            cb.AddTemplate(ImportPage, 1.0F, 0, 0, 1.0F, 0, 0)
                        End If
                    Next               
                Next
                '
                pdfDoc.Close()
                PdfW.Close()
            Catch ex As Exception
                MsgBox(ex.ToString)
            End Try

    domingo, 5 de julio de 2020 10:40

Respuestas

  • Buenos días, de nuevo.

    Al final hallé la solución: creando un array de pdfreeader para cada documento a importar en el nuevo PDF.

    Una vez cerrado dicho PDF, libero los readers. Este es el código por si a alguien le sirve:

    'NOTA: El arrayComp es que tiene el nombre de los ficheros a combinar en un nuevo PDF

    Imports iTextSharp.text
    Imports iTextSharp.text.pdf
    Imports System.IO

    Public Class ClassPDFS

        Public Sub CreaCombinaciónPDF()
            Dim NumPages As Integer
            Dim pdfR() As PdfReader    'Array de Readers
            Try
                'Archivos a insertar
                ReDim pdfR(UBound(ArrayComp))
                For iArch As Integer = 1 To UBound(ArrayComp)
                    pdfR(iArch) = New PdfReader(sAtexDirec & "\Comp\" & ArrayComp(iArch))
                Next
                'El nuevo archivo
                Dim pdfDoc As Document = New Document(PageSize.LETTER)
                'Para poder grabar el documento en disco
                Dim memo As MemoryStream = New MemoryStream
                Dim PdfW As PdfWriter = PdfWriter.GetInstance(pdfDoc,  New FileStream(sAtexDirec & "\Comp\AnexoPDF_" & sAtex & ".pdf", FileMode.Create))
                PdfW.AddViewerPreference(PdfName.PICKTRAYBYPDFSIZE, PdfBoolean.PDFTRUE)
                'Atributos del nuevo PDF
                pdfDoc.AddAuthor("ATEXPRESS")
                pdfDoc.AddTitle(sAtex)
                pdfDoc.AddCreator(MiEntidad.GetCódigoEnt)
                pdfDoc.AddCreationDate()
                'Abrimos el documento
                pdfDoc.Open()
                '
                Dim cb As PdfContentByte = PdfW.DirectContent
                '
                'Archivos a insertar
                For iArch As Integer = 1 To UBound(pdfR)
                    'pdfR = New PdfReader(sAtexDirec & "\Comp\" & ArrayComp(iArch))
                    NumPages = pdfR(iArch).NumberOfPages
                    For iPage As Integer = 1 To NumPages
                        pdfDoc.SetPageSize(pdfR(iArch).GetPageSizeWithRotation(iPage))
                        pdfDoc.NewPage()
                        Dim ImportPage As PdfImportedPage = PdfW.GetImportedPage(pdfR(iArch), iPage)
                        'Página rotada
                        Dim iRotation As Integer = pdfR(iArch).GetPageRotation(iPage)
                        If (iRotation = 90) Or (iRotation = 270) Then
                            cb.AddTemplate(ImportPage, 0, -1.0F, 1.0F, 0, 0, pdfR(iArch).GetPageSizeWithRotation(iPage).Height)
                        Else
                            cb.AddTemplate(ImportPage, 1.0F, 0, 0, 1.0F, 0, 0)
                        End If
                    Next
                    'Guarda el número de páginas en el array
                    ArrayComp(iArch) &= "##" & NumPages.ToString
                Next
                '
                pdfDoc.Close()
                PdfW.Close()

               '           

    'Cierra los Readers
                For iArch As Integer = 1 To UBound(pdfR)
                    If Not IsNothing(pdfR(iArch)) Then
                        Dim sPDF As String = pdfR(iArch).ToString
                        pdfR(iArch).Close()
                        pdfR(iArch) = Nothing
                    End If
                Next

            Catch ex As Exception
                MsgBox(ex.ToString)
            End Try
        End Sub

    • Marcado como respuesta Angelnovato lunes, 6 de julio de 2020 10:02
    lunes, 6 de julio de 2020 10:01

Todas las respuestas

  • Se te ha olvidado cerrar los ficheros que estás leyendo.

    Falta una llamada a pdfR.Close() cuando terminas de leer el fichero (es decir, entre medias de los dos "Next").

    domingo, 5 de julio de 2020 10:58
  • Hola! Lo que me comentas ya lo había intentado pero entonces el error se me da en el nuevo documento creado.

    Mensaje = No se pude tener acceso a un archivo cerrado (----Línea  del pdfDoc.Close())

    domingo, 5 de julio de 2020 11:30
  • Ese mensaje tiene pinta de ser un error de anidamiento, es decir, que lo estás cerrando antes o después de tiempo.
    domingo, 5 de julio de 2020 14:43
  • Gracias Alberto por tu interés.

    Al final he conseguido que no haya ningún error, cambiando la declaración de variables al inicio en vez de dentro de la clausula try, no se si es casualidad o no. Lo que no puedo es ponder el close del documento a leer porque siempre me da error.

    Aun así, para elmimiar los archivos antiguos insertados en el nuevo PDF tengo que salir del módulo porque parece que se quedan colgados en la memoria.

    Este el el código completo, por si quieres revisarlo:

    Imports iTextSharp.text
    Imports iTextSharp.text.pdf
    Imports System.IO

    Public Class ClassPDFS

        Public Sub CreaCombinaciónPDF()
            Dim NumPages As Integer
            Dim pdfR As PdfReader
            Try
                'El nuevo archivo
                Dim pdfDoc As Document = New Document(PageSize.LETTER)
                'Para poder grabar el documento en disco
                Dim memo As MemoryStream = New MemoryStream
                Dim PdfW As PdfWriter = PdfWriter.GetInstance(pdfDoc, New FileStream(sAtexDirec & "\Comp\AnexoPDF_" & sAtex & ".pdf", FileMode.Create))
                PdfW.AddViewerPreference(PdfName.PICKTRAYBYPDFSIZE, PdfBoolean.PDFTRUE)
                'Atributos del nuevo PDF
                pdfDoc.AddAuthor("ATEXPRESS")
                pdfDoc.AddTitle(sAtex)
                pdfDoc.AddCreator(MiEntidad.GetCódigoEnt)
                pdfDoc.AddCreationDate()
                'Abrimos el documento
                pdfDoc.Open()
                '
                Dim cb As PdfContentByte = PdfW.DirectContent
                '
                'Archivos a insertar
                For iArch As Integer = 1 To UBound(ArrayComp)
                    pdfR = New PdfReader(sAtexDirec & "\Comp\" & ArrayComp(iArch))
                    NumPages = pdfR.NumberOfPages
                    For iPage As Integer = 1 To NumPages
                        pdfDoc.SetPageSize(pdfR.GetPageSizeWithRotation(iPage))
                        pdfDoc.NewPage()
                        Dim ImportPage As PdfImportedPage = PdfW.GetImportedPage(pdfR, iPage)
                        'Página rotada
                        Dim iRotation As Integer = pdfR.GetPageRotation(iPage)
                        If (iRotation = 90) Or (iRotation = 270) Then
                            cb.AddTemplate(ImportPage, 0, -1.0F, 1.0F, 0, 0, pdfR.GetPageSizeWithRotation(iPage).Height)
                        Else
                            cb.AddTemplate(ImportPage, 1.0F, 0, 0, 1.0F, 0, 0)
                        End If
                    Next
                    'Guarda el número de páginas en el array
                    ArrayComp(iArch) &= "##" & NumPages.ToString
                Next
                '
                pdfDoc.Close()
                PdfW.Close()
            Catch ex As Exception
                MsgBox(ex.ToString)
            End Try
        End Sub

    lunes, 6 de julio de 2020 8:07
  • Buenos días, de nuevo.

    Al final hallé la solución: creando un array de pdfreeader para cada documento a importar en el nuevo PDF.

    Una vez cerrado dicho PDF, libero los readers. Este es el código por si a alguien le sirve:

    'NOTA: El arrayComp es que tiene el nombre de los ficheros a combinar en un nuevo PDF

    Imports iTextSharp.text
    Imports iTextSharp.text.pdf
    Imports System.IO

    Public Class ClassPDFS

        Public Sub CreaCombinaciónPDF()
            Dim NumPages As Integer
            Dim pdfR() As PdfReader    'Array de Readers
            Try
                'Archivos a insertar
                ReDim pdfR(UBound(ArrayComp))
                For iArch As Integer = 1 To UBound(ArrayComp)
                    pdfR(iArch) = New PdfReader(sAtexDirec & "\Comp\" & ArrayComp(iArch))
                Next
                'El nuevo archivo
                Dim pdfDoc As Document = New Document(PageSize.LETTER)
                'Para poder grabar el documento en disco
                Dim memo As MemoryStream = New MemoryStream
                Dim PdfW As PdfWriter = PdfWriter.GetInstance(pdfDoc,  New FileStream(sAtexDirec & "\Comp\AnexoPDF_" & sAtex & ".pdf", FileMode.Create))
                PdfW.AddViewerPreference(PdfName.PICKTRAYBYPDFSIZE, PdfBoolean.PDFTRUE)
                'Atributos del nuevo PDF
                pdfDoc.AddAuthor("ATEXPRESS")
                pdfDoc.AddTitle(sAtex)
                pdfDoc.AddCreator(MiEntidad.GetCódigoEnt)
                pdfDoc.AddCreationDate()
                'Abrimos el documento
                pdfDoc.Open()
                '
                Dim cb As PdfContentByte = PdfW.DirectContent
                '
                'Archivos a insertar
                For iArch As Integer = 1 To UBound(pdfR)
                    'pdfR = New PdfReader(sAtexDirec & "\Comp\" & ArrayComp(iArch))
                    NumPages = pdfR(iArch).NumberOfPages
                    For iPage As Integer = 1 To NumPages
                        pdfDoc.SetPageSize(pdfR(iArch).GetPageSizeWithRotation(iPage))
                        pdfDoc.NewPage()
                        Dim ImportPage As PdfImportedPage = PdfW.GetImportedPage(pdfR(iArch), iPage)
                        'Página rotada
                        Dim iRotation As Integer = pdfR(iArch).GetPageRotation(iPage)
                        If (iRotation = 90) Or (iRotation = 270) Then
                            cb.AddTemplate(ImportPage, 0, -1.0F, 1.0F, 0, 0, pdfR(iArch).GetPageSizeWithRotation(iPage).Height)
                        Else
                            cb.AddTemplate(ImportPage, 1.0F, 0, 0, 1.0F, 0, 0)
                        End If
                    Next
                    'Guarda el número de páginas en el array
                    ArrayComp(iArch) &= "##" & NumPages.ToString
                Next
                '
                pdfDoc.Close()
                PdfW.Close()

               '           

    'Cierra los Readers
                For iArch As Integer = 1 To UBound(pdfR)
                    If Not IsNothing(pdfR(iArch)) Then
                        Dim sPDF As String = pdfR(iArch).ToString
                        pdfR(iArch).Close()
                        pdfR(iArch) = Nothing
                    End If
                Next

            Catch ex As Exception
                MsgBox(ex.ToString)
            End Try
        End Sub

    • Marcado como respuesta Angelnovato lunes, 6 de julio de 2020 10:02
    lunes, 6 de julio de 2020 10:01
  • Hola Angelnovato,

     

    Gracias por confirmar que se ha encontrado una solución a la consulta realizada. Debido a ello, este hilo será cerrado. 

     

    Si es necesario, por favor abre un nuevo hilo. 

     

    Cualquier duda referente a productos Microsoft, puedes consultarnos. Es un gusto informarte. 

     

    Gracias por usar los foros de MSDN. 

     

    Gabriel Castro

    lunes, 6 de julio de 2020 13:02
    Moderador