如何使用 C# 将 PDF 转换为 HTML [关闭]

2023-12-03

我必须阅读 pdf 并创建 html 文档...用于在我的网站上上传的简历...我无法使用任何共享软件。 请有人建议我将 pdf 转换为 html 的最佳解决方案... 或使用 C# 读取 pdf 内容

网站是用C#、asp.net 3.5开发的


我得到了一个代码here

并下载了itextsharp 动态链接库

这段代码工作正常...我只遇到一个问题...我的大部分文件都转换为文本或 html 或我想要的任何格式...但只有 1 个文件我无法转换...如果有人的话可以使用此代码并帮助我找出问题所在...我将感谢他/她。

你可以在这里看到代码...

using System;
using System.IO;
using iTextSharp.text.pdf;
using System.Text.RegularExpressions;

namespace PDFReader
{
    /// <summary>
    /// Parses a PDF file and extracts the text from it.
    /// </summary>
    public class PDFParser
    {
        /// BT = Beginning of a text object operator 
        /// ET = End of a text object operator
        /// Td move to the start of next line
        ///  5 Ts = superscript
        /// -5 Ts = subscript

        #region Fields

        #region _numberOfCharsToKeep
        /// <summary>
        /// The number of characters to keep, when extracting text.
        /// </summary>
        private static int _numberOfCharsToKeep = 15;
        #endregion

        #endregion

        #region ExtractText
        /// <summary>
        /// Extracts a text from a PDF file.
        /// </summary>
        /// <param name="inFileName">the full path to the pdf file.</param>
        /// <param name="outFileName">the output file name.</param>
        /// <returns>the extracted text</returns>
        public bool ExtractText(string inFileName, string outFileName)
        {
            StreamWriter outFile = null;
            try
            {
                // Create a reader for the given PDF file
                PdfReader reader = new PdfReader(inFileName);
                //outFile = File.CreateText(outFileName);
                outFile = new StreamWriter(outFileName, false, System.Text.Encoding.UTF8);

                Console.Write("Processing: ");

                int totalLen = 68;
                float charUnit = ((float)totalLen) / (float)reader.NumberOfPages;
                int totalWritten = 0;
                float curUnit = 0;

                for (int page = 1; page <= reader.NumberOfPages; page++)
                {
                    outFile.Write(ExtractTextFromPDFBytes(reader.GetPageContent(page)) + " ");

                    // Write the progress.
                    if (charUnit >= 1.0f)
                    {
                        for (int i = 0; i < (int)charUnit; i++)
                        {
                            Console.Write("#");
                            totalWritten++;
                        }
                    }
                    else
                    {
                        curUnit += charUnit;
                        if (curUnit >= 1.0f)
                        {
                            for (int i = 0; i < (int)curUnit; i++)
                            {
                                Console.Write("#");
                                totalWritten++;
                            }
                            curUnit = 0;
                        }

                    }
                }

                if (totalWritten < totalLen)
                {
                    for (int i = 0; i < (totalLen - totalWritten); i++)
                    {
                        Console.Write("#");
                    }
                }
                return true;
            }
            catch
            {
                return false;
            }
            finally
            {
                if (outFile != null) outFile.Close();
            }
        }
        #endregion

        #region ExtractTextFromPDFBytes
        /// <summary>
        /// This method processes an uncompressed Adobe (text) object 
        /// and extracts text.
        /// </summary>
        /// <param name="input">uncompressed</param>
        /// <returns></returns>
        public string ExtractTextFromPDFBytes(byte[] input)
        {
            if (input == null || input.Length == 0) return "";

            try
            {
                string resultString = "";

                // Flag showing if we are we currently inside a text object
                bool inTextObject = false;

                // Flag showing if the next character is literal 
                // e.g. '\\' to get a '\' character or '\(' to get '('
                bool nextLiteral = false;

                // () Bracket nesting level. Text appears inside ()
                int bracketDepth = 0;

                // Keep previous chars to get extract numbers etc.:
                char[] previousCharacters = new char[_numberOfCharsToKeep];
                for (int j = 0; j < _numberOfCharsToKeep; j++) previousCharacters[j] = ' ';


                for (int i = 0; i < input.Length; i++)
                {
                    char c = (char)input[i];
                    if (input[i] == 213)
                        c = "'".ToCharArray()[0];

                    if (inTextObject)
                    {
                        // Position the text
                        if (bracketDepth == 0)
                        {
                            if (CheckToken(new string[] { "TD", "Td" }, previousCharacters))
                            {
                                resultString += "\n\r";
                            }
                            else
                            {
                                if (CheckToken(new string[] { "'", "T*", "\"" }, previousCharacters))
                                {
                                    resultString += "\n";
                                }
                                else
                                {
                                    if (CheckToken(new string[] { "Tj" }, previousCharacters))
                                    {
                                        resultString += " ";
                                    }
                                }
                            }
                        }

                        // End of a text object, also go to a new line.
                        if (bracketDepth == 0 &&
                            CheckToken(new string[] { "ET" }, previousCharacters))
                        {

                            inTextObject = false;
                            resultString += " ";
                        }
                        else
                        {
                            // Start outputting text
                            if ((c == '(') && (bracketDepth == 0) && (!nextLiteral))
                            {
                                bracketDepth = 1;
                            }
                            else
                            {
                                // Stop outputting text
                                if ((c == ')') && (bracketDepth == 1) && (!nextLiteral))
                                {
                                    bracketDepth = 0;
                                }
                                else
                                {
                                    // Just a normal text character:
                                    if (bracketDepth == 1)
                                    {
                                        // Only print out next character no matter what. 
                                        // Do not interpret.
                                        if (c == '\\' && !nextLiteral)
                                        {
                                            resultString += c.ToString();
                                            nextLiteral = true;
                                        }
                                        else
                                        {
                                            if (((c >= ' ') && (c <= '~')) ||
                                                ((c >= 128) && (c < 255)))
                                            {
                                                resultString += c.ToString();
                                            }

                                            nextLiteral = false;
                                        }
                                    }
                                }
                            }
                        }
                    }

                    // Store the recent characters for 
                    // when we have to go back for a checking
                    for (int j = 0; j < _numberOfCharsToKeep - 1; j++)
                    {
                        previousCharacters[j] = previousCharacters[j + 1];
                    }
                    previousCharacters[_numberOfCharsToKeep - 1] = c;

                    // Start of a text object
                    if (!inTextObject && CheckToken(new string[] { "BT" }, previousCharacters))
                    {
                        inTextObject = true;
                    }
                }

                return CleanupContent(resultString);
            }
            catch
            {
                return "";
            }
        }

        private string CleanupContent(string text)
        {
            string[] patterns = { @"\\\(", @"\\\)", @"\\226", @"\\222", @"\\223", @"\\224", @"\\340", @"\\342", @"\\344", @"\\300", @"\\302", @"\\304", @"\\351", @"\\350", @"\\352", @"\\353", @"\\311", @"\\310", @"\\312", @"\\313", @"\\362", @"\\364", @"\\366", @"\\322", @"\\324", @"\\326", @"\\354", @"\\356", @"\\357", @"\\314", @"\\316", @"\\317", @"\\347", @"\\307", @"\\371", @"\\373", @"\\374", @"\\331", @"\\333", @"\\334", @"\\256", @"\\231", @"\\253", @"\\273", @"\\251", @"\\221" };
            string[] replace = { "(", ")", "-", "'", "\"", "\"", "à", "â", "ä", "À", "Â", "Ä", "é", "è", "ê", "ë", "É", "È", "Ê", "Ë", "ò", "ô", "ö", "Ò", "Ô", "Ö", "ì", "î", "ï", "Ì", "Î", "Ï", "ç", "Ç", "ù", "û", "ü", "Ù", "Û", "Ü", "®", "™", "«", "»", "©", "'" };

            for (int i = 0; i < patterns.Length; i++)
            {
                string regExPattern = patterns[i];
                Regex regex = new Regex(regExPattern, RegexOptions.IgnoreCase);
                text = regex.Replace(text, replace[i]);
            }

            return text;
        }

        #endregion

        #region CheckToken
        /// <summary>
        /// Check if a certain 2 character token just came along (e.g. BT)
        /// </summary>
        /// <param name="tokens">the searched token</param>
        /// <param name="recent">the recent character array</param>
        /// <returns></returns>
        private bool CheckToken(string[] tokens, char[] recent)
        {
            try
            {
                foreach (string token in tokens)
                {
                    if ((recent[_numberOfCharsToKeep - 3] == token[0]) &&
                        (recent[_numberOfCharsToKeep - 2] == token[1]) &&
                        ((recent[_numberOfCharsToKeep - 1] == ' ') ||
                        (recent[_numberOfCharsToKeep - 1] == 0x0d) ||
                        (recent[_numberOfCharsToKeep - 1] == 0x0a)) &&
                        ((recent[_numberOfCharsToKeep - 4] == ' ') ||
                        (recent[_numberOfCharsToKeep - 4] == 0x0d) ||
                        (recent[_numberOfCharsToKeep - 4] == 0x0a))
                        )
                    {
                        return true;
                    }
                }
            }
            catch (Exception)
            {
              return true;
            }
            return false;
        }
        #endregion
    }
}

我在函数中收到错误“索引超出范围”

检查令牌

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 C# 将 PDF 转换为 HTML [关闭] 的相关文章

  • C# - Visual Studio 中的 System.OutOfMemoryException

    我遇到问题 当我右键单击 Visual Studio 中的主窗体并转到 视图设计器 时 出现错误 它说 引发了 System OutOfMemoryException 类型的异常 堆栈跟踪 at System Reflection Asse
  • C++0x 初始值设定项列表示例

    我想看看这个现有代码示例如何利用 C 0x 初始化列表功能 示例0 include
  • 当 foreach 块的内容具有 Conditional 属性时,C# 编译器是否会对其进行优化?

    我正在工作中编写一些调试代码 我想知道我所做的是否会损害性能 让我们看一下代码 foreach var item in aCollection Debug WriteLine item Name 我知道 Debug 类使用 Conditio
  • 何时使用 C++ 私有继承而不是组合?

    你能给我一个具体的例子吗 什么时候使用私有继承优于组合 就我个人而言 我将使用组合而不是私有继承 但在某些情况下 使用私有继承可能是特定问题的最佳解决方案 正在阅读C faq http www parashift com c faq lit
  • ASMX Web 服务,测试表单仅在本地计算机上适用于一种 WebMethod

    我有一个正在测试的 ASMX WebService 并且在大多数方法上我都可以使用测试表单进行测试 然而 我确实有一种方法 测试表上写着 The test form is only available for requests from t
  • 如何在 ASP.NET Core 6.0 Web API 项目中启用 cors?

    在我的 ASP NET Core 6 0 Web API 项目中配置了 CORS 但预检请求收到 http 405 错误 换句话说 不允许使用 HTTP OPTION 看起来 cors 没有启用 我见过的例子config EnableCor
  • 多线程 - 比单线程慢

    当我使用多个线程而不是单线程运行程序时 它会变慢 不是应该更快吗 该程序应该遍历从起始目录开始的所有目录 并查找并打印所有名为 X 的文件 代码如下 while done pthread mutex lock lock if list is
  • 根据 Active Directory 策略检查密码[重复]

    这个问题在这里已经有答案了 我有一个允许用户更改其 AD 密码的前端 有没有办法获取特定用户及其属性 长度 复杂性 的密码策略 例如细粒度 有没有办法根据此特定策略检查字符串 xyz121 编辑 我不想检查活动目录中存储的当前密码 我想检查
  • 重定向 std::cout

    我需要一个类 在其对象的生命周期内将一个 ostream 重定向到另一个 ostream 经过一番修补后 我想出了这个 include
  • 确定相关词的编程方式?

    使用网络服务或软件库 我希望能够识别与词根相关的单词 例如 座位 和 安全带 共享词根 座位 但 西雅图 不会被视为匹配 简单的字符串比较对于这类事情似乎是不可行的 除了定义我自己的字典之外 是否有任何库或 Web 服务不仅可以返回单词定义
  • 如何解决文件被另一个进程使用的问题?

    我一直在 VS NET 2010 中调试 没有任何问题 但现在无法建造 我收到错误 Unable to copy file filename to bin Debug filename The process cannot access t
  • List 或其他类型上的 string.Join

    我想将整数数组或列表转换为逗号分隔的字符串 如下所示 string myFunction List
  • Code::Blocks 中的调试似乎不起作用 - 缺少调试符号

    我正在尝试在 Code Blocks 中调试程序 我跟着本指南 http wiki codeblocks org index php title Debugging with Code Blocks and 这个短视频 http www y
  • XCode std::thread C++

    对于学校的一个小项目 我需要创建一个简单的客户端 服务器结构 它将在路由器上运行 使用 openWRT 并且我试图在这个应用程序中使用线程做一些事情 我的 C 技能非常有限 所以我在internet https stackoverflow
  • 在 lua 中加载 C++ 模块时出现“尝试索引字符串值”错误

    我正在尝试使用 lua 用 C 编写的函数 下面给出的是cpp文件 extern C include lua h include lauxlib h include lualib h static int add 5 lua State L
  • 如何使用“路径”查询 XDocument?

    我想查询一个XDocument给定路径的对象 例如 path to element I want 但我不知道如何继续 您可以使用以下方法System Xml XPath Extensions http msdn microsoft com
  • 如何获取运行或段落的高度

    我找到了Run or Paragraph in FlowDocument现在我需要知道HEIGHT of it i e while navigator CompareTo flowDocViewer Document ContentEnd
  • 使用 ASP.Net 和 Ajax 的登录页面

    我正在尝试使用 html ajax 和 ASP NET 制作登录页面 数据确实传递给 ajax 函数 但是当我调试 asp 页面时 用户名和密码以 NULL 发送 该代码应该获取用户名和密码 然后返回用户 ID html页面 div Use
  • 线程安全的有限大小队列,不使用锁

    我正在尝试编写一个主题队列 但遇到死锁和其他多线程问题 我想用Interlocked CompareExchange避免lock用法 但这段代码并没有按预期工作 它只是擦除整个队列 我在这里做错了什么 public class FixedS
  • 查找和替换正则表达式问题

    感谢这里对我其他问题的所有大力帮助 我开始掌握正则表达式 但我仍然对这个一无所知 我的代码是 StreamReader reader new StreamReader fDialog FileName ToString string con

随机推荐

  • 为什么不将函数参数存储在 XMM 向量寄存器中?

    我目前正在阅读一本书 计算机系统 程序员的视角 我发现 在 x86 64 架构上 我们仅限于 6 个整数参数 这些参数将传递给寄存器中的函数 接下来的参数将在堆栈上传递 此外 前最多 8 个 FP 或向量参数在 xmm0 7 中传递 为什么
  • 如何检测 React 应用程序中动态生成的元素外部的点击?

    我一直在与 SPA 合作React 18 and 电影数据库 TMDB API 我目前正在研究搜索功能 有一个搜索结果列表 如下所示 为了在这个列表上有一个漂亮的滚动条 我使用React Perfect 滚动条 当我点击列表外部时 我需要该
  • 为什么 Jetty 使用 text/html 内容类型提供 css

    我在 Scalatra 应用程序中使用嵌入式 Jetty 服务器 问题是它服务css文件与text html内容类型 这是主要方法 package yard web import org eclipse jetty server Serve
  • 如何在 Javascript 中获取嵌套数组的长度?

    我有一个嵌套数组的示例 var testArray 1 2 3 4 5 6 7 8 9 10 11 12 这是我获取嵌套数组长度的函数 Array prototype getLength function var sum 0 functio
  • 如何正确使用 postMessage 通过 html5 和现代浏览器进行跨域消息传递?我仍然收到错误

    我确信这里出了问题 但我不能完全指出它 这个例子here表现良好 控制台上没有任何通知或错误 因此这意味着我的浏览器支持使用 html5 进行跨域消息传递 当然是这样 它是 Chrome 14 我的代码或多或少执行以下操作 WebsiteA
  • 使用路由器 1.3.0 部署多个流时出错

    我在 1 3 0 版本上遇到以下问题 xd gt stream create test1 definition http 路由器 script file tmp file1 groovy deploy 这部署得很好 xd gt stream
  • 删除/隐藏card.io/paypal徽标android

    我正在将 Card io 集成到我的 Android 应用程序中 并且我想删除 paypal 徽标 我搜索了stackoverflow并了解了EXTRA USE CARDIO LOGO的用法 将此设置为 true 或 false 显示 Pa
  • Python:UnicodeDecodeError:'utf8'编解码器无法解码字节0x91 [关闭]

    Closed 这个问题需要调试细节 目前不接受答案 我正在解析 CSV 如下所示 with open args csv rU as csvfile try reader csv DictReader csvfile dialect csv
  • ggplot2 中轴接触处缺少像素

    我注意到 ggplot2 在 x 轴和 y 轴之间留下了一个小间隙 考虑以下代码 require ggplot2 quietly TRUE axisLines element line color black size 2 p ggplot
  • 如何在线程和 GUI 之间进行通信

    目前我使用 Kotlin 和 Java 开发桌面应用程序 GUI 是使用 JavaFX 制作的 我有几个基本的 UDP 服务器 Kotlin 线程 监听不同的端口以通过网络接收数据 连接工作正常 我可以想到几种 或多或少复杂的 线程和 GU
  • AngularJS 和 Redactor 插件

    所以我正在 AngularJS 中开发一个新网站 并且非常喜欢它 然而 我遇到了一个问题 我正在尝试向我的文本区域添加一个名为 Redactor 的 jQuery 插件 但我认为当我初始化该插件时 它会替换文本区域元素 这是有问题的原因是因
  • Cloudfront使用ssl将www重定向到裸域[关闭]

    Closed 这个问题不符合堆栈溢出指南 目前不接受答案 如果之前有人问过这个问题 请原谅我 有很多资源涉及到这个问题 但似乎没有什么适合我的特定 https 用例 我正在尝试重定向https www example com to http
  • 如何在特定位置显示自定义对话框?

    我有一个按钮 单击它会弹出一个对话框 该对话框显示在中心 但我想将它显示在按钮下方 如何做到这一点 我也尝试使用弹出窗口 这是代码 private void showPopup final Activity context Point p
  • docker 映像标识符是否可用于该 docker 内运行的进程?

    对于我的日志 我想包含 docker 映像标识符 这样我以后就可以将外部日志与生成它们的映像重新协调 有没有办法让 Docker 内部的进程获取它正在运行的图像标识符 也许是一个 dev or proc file 在 OCI 中以及之前在
  • Jetty:Spring 5 运行失败并出现 NoSuchMethodError

    我正在尝试将我的网络应用程序更新到当前的库 当我将 Spring 从 3 1 1 升级到 5 0 0 时 它开始失败 java lang NoSuchMethodError javax servlet http HttpServletRes
  • 使用 NavigationDrawer 在 Fragments 和 MapFragment 之间切换 *已修复*

    问题解决了 进一步向下滚动 我目前正在编写一个带有导航抽屉的应用程序 我想要其中一个片段中的地图 要在导航抽屉中的片段之间切换 我有这个 Switch 案例 private void displayView int position upd
  • 在类内部定义一个const静态对象变量

    我需要在类定义中创建一个静态对象 在 Java 中这是可能的 但在 C 中我得到一个错误 PlaceID h 9 43 error invalid use of incomplete type class PlaceID PlaceID h
  • 一次访问 numpy 数组中的块

    提供了一个 numpy 数组 arr np array 0 1 2 3 4 5 6 7 8 9 10 11 12 我想知道如何访问选择的大小chunks选择分离 连接和切片 例如 获取由两个值分隔的大小为 3 的块 arr chunk 3
  • 数据库更改时自动通知:类似于 facebook 好友请求

    我希望开发一个基于 php mysql 的社交网站 注册用户可以选择将其他用户添加为好友 就像在 Facebook 中所做的那样 如果用户 A 点击用户 B 个人资料上的 添加好友 链接 好友请求记录将相应地在 A 和 B 的数据库中创建
  • 如何使用 C# 将 PDF 转换为 HTML [关闭]

    很难说出这里问的是什么 这个问题模棱两可 含糊不清 不完整 过于宽泛或言辞激烈 无法以目前的形式合理回答 如需帮助澄清此问题以便重新打开 访问帮助中心 我必须阅读 pdf 并创建 html 文档 用于在我的网站上上传的简历 我无法使用任何共