Przekształcenie kliku pdf do txt....

0

Witam serdecznie mam takie pytanie chcę sobie zrobić takiego parsera który będzie mi przekształcać pdf'y do plików txt. I teraz co do jednego pliku potrafię to zrobić i nie ma problemu ale chciałbym umieścić w katalogu test załóżmy 10 plików test(x).pdf test1,test2 itd... i chciałbym je z automatu przekształcić wszystkie w txt. Jak zrobić taką pętle by czytał wszystkie pliki pdf z katalogu i przekształcał mi je w txt ?? Z góry dziękuję za pomoc.

  private void button1_Click(object sender, EventArgs e)
        {
            ExtractTextFromPdf("C:\\Users\\spectrer\\Desktop\\test\\test1.pdf");

        }

        public static string ExtractTextFromPdf(string path)
        {
            using (PdfReader reader = new PdfReader(path))
            {
                StringBuilder text = new StringBuilder();

                for (int i = 1; i <= reader.NumberOfPages; i++)
                {
                    text.Append(PdfTextExtractor.GetTextFromPage(reader, i));
                }

                return text.ToString();
            }
        }
1

http://www.csharp-examples.net/get-files-from-directory/

Przykład jak pobrać z folderu wszystkie pliki o podanym rozszerzeniu z folderu, podfolderów. W takiej tablicy stringów masz wyszczególnione te pliki, więc pętla foreach dla każdego pliku i zapisujesz je jako txt. Koniec.

0

Niby wszystko poprawnie ale nie wiem czemu nie zapisuje mi znalezionych pdf do txt... Nie mam żadnego komunikatu ;( Wszystko ładnie odczytuje ale nie zapisuje ;(
Screen z debug:
https://naforum.zapodaj.net/e524e7449847.jpg.html

I pełny kod:

 using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.parser;
using System.IO;

namespace ZestawienieFaktur
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            
        }



        private void button1_Click(object sender, EventArgs e)
        {

            string[] filePaths = Directory.GetFiles(@"D:\faktury\", "*.pdf");

            foreach (string fp in filePaths)
            {
                ExtractTextFromPdf(fp);
            }

           

        }

        public static string ExtractTextFromPdf(string path)
        {
            using (PdfReader reader = new PdfReader(path))
            {
                StringBuilder text = new StringBuilder();

                for (int i = 1; i <= reader.NumberOfPages; i++)
                {
                    text.Append(PdfTextExtractor.GetTextFromPage(reader, i));
                }

                return text.ToString();

            }
            
        }
    }
}

1

Cóż odpowiedź jest bardzo prosta, nigdzie nie masz kodu do zapisywania tekstu wydobytego z pliku pdf.

0

Coś nie wychodzi mi ;( Mam błąd ...ExtractTextFromPdf Nie wszystkie ścieżki kodu zwracają wartość...

         private void button1_Click(object sender, EventArgs e)
        {

            string[] filePaths = Directory.GetFiles(@"D:\faktury\", "*.pdf");

           foreach (string fp in filePaths)
            {
                ExtractTextFromPdf(fp);
            }
          
        }

        public static string ExtractTextFromPdf(string path)
        {
            using (PdfReader reader = new PdfReader(path))
            {
                StringBuilder text = new StringBuilder();

                for (int i = 1; i <= reader.NumberOfPages; i++)
                {
                    text.Append(PdfTextExtractor.GetTextFromPage(reader, i));
                }

                string lines = text.ToString();
                using (var file = new StreamWriter(@"D:\faktury\test1.txt"))
                {
                    file.WriteLine(lines);
                    file.Close();
                }

            }
0

a gdzie zwracasz wartość z funkcji ExtractTextFromPdf?

0

Sorki bo testowałem tylko czy utwporzy mi plik ale kiedy jak w przypadku return daję string lines = text.ToString(); to i tak my wywala błąd... Ale nie wiem czy nie trzeba to wcześniej gdzieś do tablicy wrzucić i potem do pliku ??

1

nie wiem gdzie to wstawiałeś ale jak już to tu

string lines = text.ToString();
                using (var file = new StreamWriter(@"D:\faktury\test1.txt"))
                {
                    file.WriteLine(lines);
                    file.Close();
                }
                return lines; //albo od razu return text.ToString();
            }
0

Ok dzięki działa super... ogarnąłem sobie zapis o takiej samej nazwie pliku do txt i teraz chciałem z plików txt wyciągnąć interesujące mnie pola z faktury i poległem bo nie wiem jak wrzucić to do GridView ;( Okodowoałem sobie taki button i wyrażenia regularne są prawidłowe bo wyświetla mi prawidłowe wartości... Jakby ktoś by mi mógł pomóc... Bo stanąłem w martwym punkcie ;(

private void button2_Click(object sender, EventArgs e)
        {
            string newPath = (Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\faktury\\");
            string[] filePaths = Directory.GetFiles(newPath, "*.txt");

            foreach (string fp in filePaths)
            {
                string[] lines = File.ReadAllLines(fp);

                // Iterate through lines
                foreach (string line in lines)
                {

                    foreach (Match match in Regex.Matches(line, @"Numer Faktury:(.*?)$", RegexOptions.IgnoreCase))
                    {
                        
                        MessageBox.Show(match.Groups[1].Value);

                    }
                    foreach (Match match in Regex.Matches(line, @"Data wystawienia: (.*?)$", RegexOptions.IgnoreCase))
                    {
                      
                        MessageBox.Show(match.Groups[1].Value);

                    }
                    foreach (Match match in Regex.Matches(line, @"Wartość netto  (.*?) PLN", RegexOptions.IgnoreCase))
                    {
                        
                        MessageBox.Show(match.Groups[1].Value);

                    }
                    foreach (Match match in Regex.Matches(line, @"Wartość całkowita VAT 8 %  (.*?) PLN", RegexOptions.IgnoreCase))
                    {

                        MessageBox.Show(match.Groups[1].Value);

                    }
                    foreach (Match match in Regex.Matches(line, @"Wartość brutto  (.*?) PLN", RegexOptions.IgnoreCase))
                    {

                        MessageBox.Show(match.Groups[1].Value);

                    }
                }
 
1

zrób sobie klasę np. Faktura z właściwościami, które potrzebujesz

class Faktura
{
  public string NrFaktury { get; set; }
  public Date DataFaktury { get; set; }
  public double Netto { get; set; }
  public double Brutto{ get; set; }
  public double Vat{ get; set; }
}

i listę tych klas

  var ListaFaktur = new List<Faktura>();

a potem https://www.google.pl/search?q=displaying+list+in+datagridview+c%23

w pierwszym linku z SO masz ładny przykład jak się z tym obchodzić.

0

Kolejny dzień walki... Dodałem sobie do klasy tak jak sugerowałeś nie wiem czy dobrze ale tak to ogarnąłem jak poniżej... i mam taki problem że chce mieć 5 kolumn tak jak jest 5 właściwości.
Kombinuje i ciągle mi wyświetla jeden pod drugim ;( a chce by z każdego pliku wchodziło tylko 5 wartości i przechodziło do następnego wierszu. Czyli jedna faktura = 1 wiersz.
Ale jak zrobię jak poniżej to oczekuje results.Add(new ShowResults(...)) 5 parametrów bo takie zdefiniowane są public ShowResults. A jak zrobić żeby był 1 parametr dla 1 kolumny ?? ;)
Z góry dziękuję za pomoc...

Teraz mam takie coś:
https://naforum.zapodaj.net/eda9f58324b7.jpg.html

  public class ShowResults
        {
            public string NrFaktury { get; set; }
            public string Data_wystawienia { get; set; }
            public double Netto { get; set; }
            public double Brutto { get; set; }
            public double Vat { get; set; }

            public ShowResults(string nf, string dw, string nt, string bt, string vt)
            {
                this.NrFaktury = nf;
                this.Data_wystawienia = dw;
                this.Netto = nt;
                this.Brutto = bt;
                this.Vat = vt;

            }


        }

I button:

 private void button2_Click(object sender, EventArgs e)
        {
            string newPath = (Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\faktury\\");
            string[] filePaths = Directory.GetFiles(newPath, "*.txt");


            List<ShowResults> results = new List<ShowResults>();

            foreach (string fp in filePaths)
            {
                string[] lines = File.ReadAllLines(fp);

                // Iterate through lines
                foreach (string line in lines)
                {

                    foreach (Match match in Regex.Matches(line, @"(Numer Faktury:|Numer faktury korygującej: )(.*?)$", RegexOptions.IgnoreCase))
                    {

                        results.Add(new ShowResults(match.Groups[2].Value));

                    }
                    foreach (Match match in Regex.Matches(line, @"(Data wystawienia:|Data wystawienia korekty:)(.*?)$", RegexOptions.IgnoreCase))
                    {

                        results.Add(new ShowResults(match.Groups[2].Value));

                    }
                    foreach (Match match in Regex.Matches(line, @"Wartość netto  (.*?) PLN", RegexOptions.IgnoreCase))
                    {

                        results.Add(new ShowResults(match.Groups[1].Value));

                    }
                    foreach (Match match in Regex.Matches(line, @"Wartość całkowita VAT 8 %  (.*?) PLN", RegexOptions.IgnoreCase))
                    {

                        results.Add(new ShowResults(match.Groups[1].Value));

                    }
                    foreach (Match match in Regex.Matches(line, @"Wartość brutto  (.*?) PLN", RegexOptions.IgnoreCase))
                    {

                        results.Add(new ShowResults(match.Groups[1].Value));

                    }

                    
                }
                


            }
            dataGridView1.DataSource = results;
        }
1

robiąc tak za każdym razem dodajesz do listy nową pozycję zamiast dodać jedną z wszystkimi wartościami. Nie proponowałem bo nie wiem ile faktur masz w linii.

po
foreach (string line in lines)
{

dodaj
res = new ShowResults();

i w pierwszym foreach zamiast
results.Add(new ShowResults(match.Groups[2].Value));
daj
res.NrFaktury = match.Groups[2].Value;

i tak w każdym kolejnym foreach podstawiając odpowiednie właściwości.
Na koniec przed
}
}
dataGridView1.DataSource = results;
}

dodaj
results.Add(res);

Pewnie też trzeba będzie konstruktor z klasy ShowResults wywalić bo jest zbędny

0

Coś nie tak wywala mi błąd:
https://zapodaj.net/1590dec1bf448.jpg.html

res = new ShowResults();

Chyba powinno być:

ShowResults res = new ShowResults();

Po poprawieniu mam taki rezultat ;/
https://zapodaj.net/ed4f32385204c.jpg.html

Pełny kod:

 public class ShowResults
        {
            public string NrFaktury { get; set; }

           }
        private void button2_Click(object sender, EventArgs e)
        {
            string newPath = (Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\faktury\\");
            string[] filePaths = Directory.GetFiles(newPath, "*.txt");


            List<ShowResults> results = new List<ShowResults>();

            foreach (string fp in filePaths)
            {
                string[] lines = File.ReadAllLines(fp);
                ShowResults res = new ShowResults();
                // Iterate through lines
                foreach (string line in lines)
                {

                    foreach (Match match in Regex.Matches(line, @"(Numer Faktury:\s|Numer faktury korygującej:\s)(.*?)$", RegexOptions.IgnoreCase))
                    {

                        res.NrFaktury = match.Groups[2].Value;
                    }

                  
                   

                    }

                    results.Add(res);
                }
                


            }
            dataGridView1.DataSource = results;
        }
1

no ale to ja nie mam pojęcia co masz w tych plikach, które dostajesz po przekonwertowaniu PDFa do TXT. TO zadziała tylko wtedy jeśli WSZYSTKIE dane faktury będą w jednej linii.

0

Ogarnąłem ale coś dalej nie tak ;) Teraz mam układ ok ale 24 kopie ;) Jak w katalogu tylko jedna faktura jest z danymi które chce wyciągnąć.. Kod wkleiłem do wcześniejszego posta...

https://zapodaj.net/a45b69449e362.jpg.html

EDIT:
OK już wiem trzeba było przesunąć

 results.Add(res);

i jest już wszystko oki dzięki wielkie za pomoc. Po prostu wykonywał pętle dla każdej linii a nie dla pliku ;)

1

VAT i BRUTTO Ci się pozamieniały

0

Wiem... poprawiłem to po wrzucie screena ;) Dzięki jeszcze raz za pomoc...

1 użytkowników online, w tym zalogowanych: 0, gości: 1