0

我需要编写一个应用程序或查询来将大量 PDF 导出到文件并创建一个分隔文本文件,以显示文件的位置并包含记录的 ID。

我正在考虑做的是使用控制台应用程序,该应用程序将在从数据库导出 PDF 后将条目写入文本文件,这样我在编写文本文件时将所有信息放在一起,这样我就可以确保所有分隔文本文件中的数据是准确的。

起初我正在考虑使用 Dataset 来执行此操作,但会有超过 50,000 行 Data。我不太确定 DataTable 会更好

我也在考虑使用 BCP 实用程序,但从我阅读的内容来看,导出并没有给我从数据中返回的 PDF 文件,这是真的吗?

我可能会认为自己是初学者,编写这样的程序。我应该为这样的数据结构使用什么?我会使用光标吗?如果是这样,我将如何设置它以适应我正在做的事情?

更新

我将尝试使用 DataSet 选项,但使用 do while 循环将其一次限制为 1 天的数据,以便我可以从数据开始到今天的每一天循环。所以我会做一天的数据,然后摆脱数据集,然后做下一个日期。

有人在我的逻辑中看到任何会导致问题的东西吗?

4

1 回答 1

1

当我最终研究完解决问题的所有不同方法时,编写代码真的很简单。我根本没有使用 BCP。

我为要在文本文件中提取的信息创建了变量。

  1. 文件名
  2. 日期(来自原始创建日期的 SQL 表)
  3. 案例编号(要链接到的第 3 方程序的内部标识符)
  4. 描述(取自 SQL 表来描述文档)

然后我让应用程序开始工作 一次将代码写入 PDF

using (SqlConnection Conn = new SqlConnection(strSQLConn))
        {
            //open the connection
            Conn.Open();
            Console.WriteLine("the connection is open");

            //Variables needed for looping
            DateTime Today = System.DateTime.Now;
            DateTime StartDate = Convert.ToDateTime("2008-06-11 00:00:00");
            //DateTime StartDate = Today.AddDays(-10);
            Console.WriteLine("Converting the Documents from " + StartDate.ToString() + " - TO - " + Today.ToString());
            Console.WriteLine("Press Any Key to continue.");
            Console.ReadLine();
            int RecordCount = 0;
            ulong ByteCount = 0;
            int i = 1;
            foreach (DateTime day in EachDay(StartDate, Today))
            {
                String strDay = day.ToString();
                // Create a SQLCommand to retrieve Data
                SqlCommand getRecords = new SqlCommand("spRecapturePDF", Conn);
                getRecords.CommandType = CommandType.StoredProcedure;
                getRecords.Parameters.Add(new SqlParameter("@OneDay", strDay));
                SqlDataReader reader = getRecords.ExecuteReader();
                //stuff exporting the binary code to the PDF format
                FileStream fs;
                BinaryWriter bw;
                int buffersize = 100;
                byte[] outbyte = new byte[buffersize];
                long retval;
                long startIndex = 0;

                int j = 1;

                while (reader.Read())
                {
                    strFileName = reader.GetString(0) + "-" + i + "-" + j;
                    strDock_no = reader.GetString(0);
                    dtFiledate = reader.GetDateTime(2);
                    strDescription = reader.GetString(4);   
                    fs = new FileStream("c:\\FolderName\\" + strFileName + ".pdf", FileMode.OpenOrCreate, FileAccess.Write);
                    bw = new BinaryWriter(fs);
                    startIndex = 0;
                    retval = reader.GetBytes(1,startIndex,outbyte,0,buffersize);
                    while (retval == buffersize)
                    {
                        bw.Write(outbyte);
                        bw.Flush();
                        startIndex += buffersize;
                        retval = reader.GetBytes(1,startIndex,outbyte,0,buffersize);
                    }
                    //write the remaining buffer.
                    bw.Write(outbyte,0,(int)retval);
                    ByteCount = ByteCount + Convert.ToUInt64(fs.Length);
                    bw.Flush();
                    //close the output file
                    bw.Close();
                    fs.Close();
                    //need to write to the Text file here.
                    TextWriter tw = new StreamWriter(path,true);
                    tw.WriteLine(strDock_no + "~" + dtFiledate.ToString() + "~" + "c:\\FolderName\\" + strFileName + ".pdf" + "~" + strDescription);
                    tw.Close();
                    // increment the J variable for the Next FileName
                    j++;
                    RecordCount++;
                }
             //close the reader and the connection
                reader.Close();
                i++;
            }
        Console.WriteLine("Number of Records Processed:  " + RecordCount.ToString());
            Console.WriteLine("for a Total of : " + ByteCount + " Bytes");

            Decimal MByteCount = new Decimal(2);
            MByteCount = Convert.ToDecimal(ByteCount) / 1024 / 1024;
            Decimal GByteCount = new Decimal(2);
            GByteCount = MByteCount / 1024;

            Console.WriteLine("Total MBs : " + MByteCount.ToString() + " MB");
            Console.WriteLine("Total GBs : " + GByteCount.ToString() + " GB");
            Console.WriteLine("Press Enter to Continue ...");
            Console.ReadLine();
        }

本准则包含在foreach从开始日期到结束日期逐日进行的声明中。在该foreach语句中,应用程序调用了一个存储过程,该存储过程被赋予了指定的日期来调用当天输入的记录。

变量i并被j创建是因为即使我有相同的案例编号,我也需要有一个唯一的文件名。 i代表这一天(因为我在我的 select 语句中一天一天过去)并j代表了 select 语句中那一天的记录号。

theforeachwhile循环被封闭在 a 中using(conn),因此无论什么连接最终都会关闭。

在 while 循环结束时,我写入了文本文件。文本文件是在所有循环之外创建的,这样我就可以附加文件而不是覆盖它。该代码是:

string path = @"c:\\FolderName\\TextFile.txt";
        if (!File.Exists(path))
        {
            TextWriter tw = new StreamWriter(path, false);
            tw.WriteLine("Dock_No~Date~FileName(Location)~Description");
            tw.Close();
        }

我希望这对其他人有帮助。我省略了我正在寻找的功能所不需要的所有代码Console.WritelineConsole.ReadLine我还添加了一些代码来计算写入的字节数和一些代码来计算处理的记录。这只是有趣的东西,我需要在最后清理有趣的东西。

这些是从 SQL Server 中的 Blob 字段中完成大量 PDF 提取所需的勇气,减去一些 Connection Mumbo Jumbo

Foreach 日设置

这是我用来按照foreach我想要的方式进行工作的代码。

static public IEnumerable<DateTime> EachDay(DateTime Startdate, DateTime EndDate)
    {
        for (var day = Startdate.Date; day.Date <= EndDate.Date; day = day.AddDays(1))
            yield return day;
    }
于 2013-07-30T18:26:31.023 回答