Hola. Tengo unos cuantos ficheros en PDF que necesito convertir a CSV o similar para posteriormente hacer una importación hacia una base de datos.
La conversión de PDF a texto ya la tengo funcionando, el "problema" lo tengo con que los ficheros pdf vienen con los datos tabulados en columnas, con lo cual, cuando ha la conversión texto, dichas tabulaciones las pierdo y lo que me vienen son lineas de texto en "bruto" y únicamente separadas por espacios. O al menos eso es lo que me parece a mí.
Intenté hacer un replace buscando los TAB y sustituyendo por ";", pero no me pareció funcionar.
Posteriormente he ido complicándolo un poco y estoy preparando un proceso para que vaya cogiendo datos de cada línea en función de los espacios en blanco que se van encontrando. El problema que tengo con esto es que no todos los nombres tienen nombre y dos apellidos, etc.
¿Se os ocurre a alguno como poder hacer esto de la manera más "flexible"?
Lo que tengo hecho hasta ahora me funcioan, pero solo en parte ya que no todos los nombres están compuestos por el mismo número de palabras.
Y el resultado:
Si os fijáis, para la segunda columna le tengo definidos que tenga en cuenta dos espacios, con lo cual, en la primera fila, la de los títulos ya no pone el ";" después de UserName y luego en la última fila, la que empieza por 19, como el nombre es solo un 0, el uno de la siguiente columan lo une al nombre y coge el contenido de la siguiente columna.
La conversión de PDF a texto ya la tengo funcionando, el "problema" lo tengo con que los ficheros pdf vienen con los datos tabulados en columnas, con lo cual, cuando ha la conversión texto, dichas tabulaciones las pierdo y lo que me vienen son lineas de texto en "bruto" y únicamente separadas por espacios. O al menos eso es lo que me parece a mí.
Intenté hacer un replace buscando los TAB y sustituyendo por ";", pero no me pareció funcionar.
Posteriormente he ido complicándolo un poco y estoy preparando un proceso para que vaya cogiendo datos de cada línea en función de los espacios en blanco que se van encontrando. El problema que tengo con esto es que no todos los nombres tienen nombre y dos apellidos, etc.
¿Se os ocurre a alguno como poder hacer esto de la manera más "flexible"?
Lo que tengo hecho hasta ahora me funcioan, pero solo en parte ya que no todos los nombres están compuestos por el mismo número de palabras.
B4X:
Project Attributes
#MainFormWidth: 600
#MainFormHeight: 400
#End Region
Sub Process_Globals
Private fx As JFX
Private MainForm As Form
Private Button1 As Button
Private TextArea1 As TextArea
Private TextArea2 As TextArea
Private TableView1 As TableView
Private TableView2 As TableView
Private TextArea3 As TextArea
Private Button2 As Button
Dim Lineas As List
End Sub
Sub AppStart (Form1 As Form, Args() As String)
MainForm = Form1
MainForm.SetFormStyle("UNIFIED")
MainForm.RootPane.LoadLayout("test") 'Load the layout file.
MainForm.Show
End Sub
Sub SplitGetWords(txt As String, SplitCharacter As String, Index As Int, Count As Int) As String
Private words() As String
words = Regex.Split(SplitCharacter, txt)
Dim Aux As String
Dim i As Int
For i = 0 To Count-1
If i > 0 Then Aux = Aux & " "
Aux = Aux & words(Index+i)
Next
Return Aux
End Sub
Sub Button1_MouseClicked (EventData As MouseEvent)
Dim fc As FileChooser
fc.Initialize
Dim PDF As jPDFBoxDocument
Dim Texto As String
Dim FileName As String = fc.ShowOpen(MainForm)
PDF.Initialize(FileName)
Log(PDF.NumberOfPages)
'Extracts all pages
Texto = PDF.ExtractText
TextArea1.Text = Texto
' Convierto la string en una lista para poder trabajar con ella mejor.
File.WriteString(File.DirApp, "Pdf2Txt.txt", Texto)
Lineas.Initialize
Lineas = File.ReadList(File.DirApp, "Pdf2Txt.txt")
'Optional Extract only a range of pages
'TextArea1.Text = PDF.ExtractText2(1, 2)
PDF.Close
End Sub
Sub Button2_Click
Dim NLinea As Int
Dim NLineaIni As Int = 1
Dim Linea As String
Dim Resul, Aux As String
Dim ResulLineas As List
ResulLineas.Initialize
For NLinea = NLineaIni To Lineas.Size -1
Linea = Lineas.Get(NLinea)
Resul = ""
Log(NLinea & " - " & Linea)
Aux = SplitGetWords(Linea, " ", 0, 1)
Resul = Resul & Aux & ";"
Linea = Linea.SubString(Aux.Length)
Aux = SplitGetWords(Linea, " ", 1, 2)
Resul = Resul & Aux & ";"
Linea = Linea.SubString(Aux.Length)
ResulLineas.Add(Resul)
Log(Resul)
Next
File.WriteList(File.DirApp, "Resul.csv", ResulLineas)
End Sub
Y el resultado:
B4X:
UserID;UserName UserType;
1;Bill Administrator;1;
9;Mike Whetmore;1;
10;John Barns;1;
11;Default Demo;1;
12;Donna Booth;1;
13;Alan Hoza;1;
14;Frank Tatlow;1;
15;Frank Tatlow;1;
16;Master Admin;1;
17;El Nin;1;
18;El Cero;1;
19;0 1;Error;
Si os fijáis, para la segunda columna le tengo definidos que tenga en cuenta dos espacios, con lo cual, en la primera fila, la de los títulos ya no pone el ";" después de UserName y luego en la última fila, la que empieza por 19, como el nombre es solo un 0, el uno de la siguiente columan lo une al nombre y coge el contenido de la siguiente columna.