【问题标题】:How to update a PDF file?如何更新 PDF 文件?
【发布时间】:2013-04-04 19:25:18
【问题描述】:

我需要在 ASP.NET 的 PDF 文档中用用户从下拉列表中选择的新词替换一个词。我正在使用 iTextSharp ,但创建的新 PDF 全部失真,因为我无法在提取时提取 PDF 的格式/样式信息。另外,有没有办法逐行阅读pdf?请帮忙..

    protected void Page_Load(object sender, EventArgs e)
    {
        String s = DropDownList1.SelectedValue;
        Response.Write(s);
        ListFieldNames(s);
    }
    private void CreatePDF(string text)
    {
        string outFileName = @"z:\TEMP\PDF\Test_abc.pdf";
        Document doc = new Document();
        doc.SetMargins(30f, 30f, 30f, 30f);
        PdfWriter.GetInstance(doc, new FileStream(outFileName, FileMode.Create));
        doc.Open();
        BaseFont bfTimes = BaseFont.CreateFont(BaseFont.COURIER, BaseFont.CP1252, false);
        Font times = new Font(bfTimes, 12, Font.BOLDITALIC);
        //Chunk ch = new Chunk(text,times);
        Paragraph para = new Paragraph(text,times);

        //para.SpacingAfter = 9f;
        para.Alignment = Element.ALIGN_CENTER;
        //para.IndentationLeft = 100;
        doc.Add(para);


        //doc.Add(new Paragraph(text,times));
        doc.Close();
        Response.Redirect(@"z:\TEMP\PDF\Test_abc.pdf",false);




    }

    private void ListFieldNames(string s)
    {
        ArrayList arrCheck = new ArrayList();
        try
        {
            string pdfTemplate = @"z:\TEMP\PDF\abc.pdf";
            //string dest = @"z:\TEMP\PDF\Test_abc.pdf";

            PdfReader pdfReader = new PdfReader(pdfTemplate);
            string pdfText = string.Empty;
            string extracttext = "";
            for (int page = 1; page <= pdfReader.NumberOfPages; page++)
            {

                ITextExtractionStrategy its = new iTextSharp.text.pdf.parser.SimpleTextExtractionStrategy();
                PdfReader reader = new PdfReader((string)pdfTemplate);
                extracttext = PdfTextExtractor.GetTextFromPage(reader, page, its);
                extracttext = Encoding.Unicode.GetString(ASCIIEncoding.Convert(Encoding.Default, Encoding.Unicode, Encoding.Default.GetBytes(extracttext)));
                pdfText = pdfText + extracttext;

                pdfText = pdfText.Replace("[xyz]", s);
                pdfReader.Close();
            }

            CreatePDF(pdfText);
        }
        catch (Exception ex)
        {

        }
        finally
        {

        }
    }

【问题讨论】:

  • iText 解析器类(尚未)用于重新构建 PDF,而仅用于(纯)文本和图像提取以及它们的位置和尺寸的提取。此外请注意,PDF 不是可编辑格式; 用一个新词替换一个词, 因此,这不是一件小事,而是(对于通用解决方案)一项艰巨的任务。话虽如此,如果您的任务仅限于一种特殊类型的 PDF,请张贴样本以供检查,也许您的文档的构建方式大大简化了任务。
  • 单词替换工作正常。但是,这段代码创建的新 PDF 没有实际的所有样式信息。有什么方法可以提取 PDF 的样式信息以及文本...?
  • 您对提取的纯文本进行单词替换。如果这就是你想要的,那就太好了。否则完全不相关。
  • +1 @mkl 的评论

标签: asp.net c#-4.0 pdf itextsharp


【解决方案1】:

你一个接一个地做出错误的假设。

  1. 您假设 PDF 中存在“线条”的概念。这是错误的。在 Text State 中,不同的文本 sn-ps 被绘制在页面上的绝对位置。对于每个“显示文本”运算符,iText 将返回一个 TextRenderInfo 对象,其中包含已绘制的文本部分及其坐标。一行可以包含多个文本 sn-ps。文本 sn-p 可能包含空格,甚至可能为空。
  2. 您假设 PDF 中的所有文本都保持其自然阅读顺序。这对于 PDF/UA 应该是正确的(UA 代表通用可访问性),但对于您可以在野外找到的大多数 PDF 肯定不是这样。这就是 iText 提供基于位置的文本提取的原因(参见iText in Action, Second Edition 的 p521)。如 p516 中所述,文本“Hello World”可以在 PDF 中存储为“ld”、“Wor”、“llo”、“He”。 LocationTextExtractionStrategy 将排序所有文本 sn-ps,必要时重构单词。例如:它将“He”和“llo”连接到“Hello”,因为“He”sn-p 和“llo”sn-p 之间没有足够的空间。但是,由于未知原因(可能是无知),您使用的是 SimpleTextExtractionStrategy,它不会根据位置对文本进行排序。
  3. 您完全忽略了所有图形状态运算符,以及定义字体的文本状态运算符等...
  4. 您假设 PDF 是一种文字处理格式。这在许多层面上都是错误的,您的代码也是如此。请阅读chapter 6 of my book的介绍。

所有这些错误的假设几乎让我想对你的问题投反对票。冒着被自己否决这个答案的风险,我必须告诉你,你不应该尝试“做同样的事情”。你问的问题非常复杂,在很多情况下甚至是不可能的!

【讨论】:

  • 实际上单词替换工作正常。但是,这段代码创建的新 PDF 没有实际的所有样式信息。有什么方法可以提取 PDF 的样式信息以及文本...?
  • 正如我在回答的第 3 点中解释的那样,您忽略了所有图形状态和文本状态运算符。如果你不相信我说你做了太多错误的假设,请开始阅读 ISO-32000-1。
猜你喜欢
  • 2015-10-31
  • 2011-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-27
  • 1970-01-01
  • 1970-01-01
  • 2013-04-11
相关资源
最近更新 更多