2020年6月15日 星期一

[研究][C#][ASP.NET] 使用 Free Spire.PDF for NET v6.2.0 取代 .pdf 中的文字

[研究][C#][ASP.NET] 使用 Free Spire.PDF for NET v6.2.0 取代 .pdf 中的文字

2020-06-13
2020-06-15  補充
2020-06-21 更新
2020-06-30 更新

範例程式
https://www.e-iceblue.com/Knowledgebase/Spire.PDF/Program-Guide/Text/Find-and-replace-text-on-PDF-document-in-C.html

免費版限制
https://www.e-iceblue.com/Download/download-pdf-for-net-free.html
免費版本可以商業使用或個人使用,但有 10 頁 pdf 限制 (讀取 or 建立檔案),若把 .pdf 轉成圖片,只能轉3頁。要更強功能,請用商業版。

Thank you for your interests in our Free Spire.PDF for .NET. It is totally free without any warning message for your commercial and personal use. Free version is limited to 10 pages of PDF. This limitation is enforced during loading and creating files. When converting PDF to Image, the first 3 pages of PDF files will be converted to Image format successfully.

If your requirements exceed the limitation, please use our Commercial Edition of Spire.PDF.

Visual Studio 2019 v16.6.2 + C# + ASP.NET + WebForm + WebApplication
NuGet 要安裝 Free Spire.PDF for NET v6.2.0 

Default.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="ReplaceTextbySpirePDF.Default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
        </div>
    </form>
</body>
</html>


Default.aspx.cs

using Spire.Pdf;
using Spire.Pdf.General.Find;
using Spire.Pdf.Graphics;
using System;
using System.Drawing;

namespace ReplaceTextbySpirePDF
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            // https://www.e-iceblue.com/Knowledgebase/Spire.PDF/Program-Guide/Text/Find-and-replace-text-on-PDF-document-in-C.html
            // Step 1: Load the sample document file.

            PdfDocument doc = new PdfDocument();
            doc.LoadFromFile(@"C:\Temp\樣張-2020-06-09.pdf");

            // Step 2: Searched the text “Spire.PDF for .NET” from the first page of the sample document.

            PdfPageBase page = doc.Pages[0];
            PdfTextFindCollection collection = page.FindText("{@大學}", TextFindParameter.IgnoreCase);

            // Step 3: Use the new string “E - iceblue Spire.PDF” to replace the searched text and sent the font and color for the new string.

            String newText = "測試大學";
            //String newText = "ABC";
            //Creates a brush
            PdfBrush brush = new PdfSolidBrush(Color.DarkBlue);
            
            //Defines a font
            // 中文字亂碼,若 newText 為英文字可用,但英文 12f 改 14f, 16f, 18f 可用,但 20f, 22f 會空白
            //PdfTrueTypeFont font = new PdfTrueTypeFont(new Font("Arial", 18f, FontStyle.Regular));    

            //【Spire.PDF】出现中文乱码,中文显示不正常的情况
            // https://blog.csdn.net/weixin_38211198/article/details/89192598
            //Font font0 = new Font("Arial", 10, FontStyle.Regular, GraphicsUnit.Point, 1, true);    
            //Font font0 = new Font("DFKai-SB", 10, FontStyle.Regular, GraphicsUnit.Point, 1, true);
            //Font font0 = new Font("DFKai-SB", 22, FontStyle.Regular, GraphicsUnit.Point, 1, true); 
            //Font font0 = new Font("DFKai-SB", 22, FontStyle.Regular); 
            Font font0 = new Font("標楷體", 18, FontStyle.Bold);   // 中文字體 不可超過18,19開始會變成空白
            //Font font0 = new Font("新細明體", 19, FontStyle.Regular);   // 英文字、中文字變成空白
            PdfTrueTypeFont font = new PdfTrueTypeFont(font0, true);   // 標楷體,中文字亂碼,true 表示 unicode

            RectangleF rec;
            foreach (PdfTextFind find in collection.Finds)
            {
                // Gets the bound of the found text in page
                rec = find.Bounds;
                page.Canvas.DrawRectangle(PdfBrushes.White, rec);
                page.Canvas.DrawString(newText, font, brush, rec);
                // https://www.e-iceblue.cn/spirepdf/set-font-for-pdf.html
                //page.Canvas.DrawString(newText, font, brush, new PointF(50,50));
            }

            // Step 4: Save the document to file.

            doc.SaveToFile(@"C:\Temp\樣張-2020-06-15.pdf");
        }
    }
}

若要彈出 pdf 下載對話盒視窗

Response.Clear();
Response.Buffer = true;
Response.Charset = "";
string mainFileName = "主要檔案名稱";
string dateTimeString = DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss-fff");

// 若檔案名稱有中文字或特殊符號,Response.AddHeader() 輸出檔案名稱要編碼
string outFileName = HttpUtility.UrlEncode(mainFileName, System.Text.Encoding.UTF8) + "-" +
    dateTimeString + ".pdf";

// XLWorkbook.SaveAs() 輸出檔案名稱不要用 HttpUtility.UrlEncode 編碼
// Response.TransmitFile() 輸出檔案名稱不要用 HttpUtility.UrlEncode 編碼
string dirFileName = @"C:\TEMP\" + mainFileName + "-" +
    dateTimeString + ".pdf";

Response.ContentType = "application/octet-stream";
Response.ContentEncoding = Encoding.UTF8;
Response.AddHeader("content-disposition", "attachment;filename=" + outFileName);
Response.TransmitFile(dirFileName);
Response.Flush();
Response.End();

中文字的問題,可參考這裡。
https://www.e-iceblue.com/Tutorials/Spire.PDF/Spire.PDF-Program-Guide/Text/How-to-add-simplified-and-traditional-Chinese-characters-to-PDF-in-C-VB.NET.html

因為字體只能小於等於 18,若超過,可能要結合下面2篇去產生;或者有辦法用  Free Spire.PDF for NET v6.2.0  直接替換字型大小 18 的字。

[研究][C#][ASP.NET] 用 NPOI 替換 Word (.docx) 中的文字

[研究][C#][ASP.NET] 使用 FreeSpire.Doc 7.11.0 把 .docx 轉成 .pdf

********************************************************************************
2020-06-15  補充

發現字體大小限制問題問題來自 rec 的範圍大小,限制了文字字串可用的高度、寬度,上面程式 rec 是根據被替換的字 {@大學} 計算大小,所以字大些就放不下。程式片段改成如下(整段文字組合好,把幾個字,換成整段文字;不是把幾個字只取代成幾個字。


foreach (PdfTextFind find in page.FindText("{$茲證明}", TextFindParameter.IgnoreCase).Finds)
            {
                rec = find.Bounds;
                page.Canvas.DrawRectangle(PdfBrushes.White, rec);
                rec.Width = PdfPageSize.A4.Width - rec.X *2;
                rec.Height = rec.Y + 72;   // 72 是自己測試隨便放的值,高度夠就好。
                page.Canvas.DrawString("茲證明那一整串字。", new PdfTrueTypeFont(new Font("標楷體", 22, FontStyle.Bold), true), brush, rec );
            }
foreach (PdfTextFind find in page.FindText("{$中華民國}", TextFindParameter.IgnoreCase).Finds)
            {
                rec = find.Bounds;
                page.Canvas.DrawRectangle(PdfBrushes.White, rec);
                rec.Width = PdfPageSize.A4.Width - rec.X * 2;
                rec.Height = rec.Y + 20;
                string date = "中\t華\t民\t國\t" + (DateTime.Now.Year - 1911).ToString() + "\t年\t" + DateTime.Now.Month.ToString() + "\t月\t" + DateTime.Now.Day.ToString() + "\t日";
                page.Canvas.DrawString(date, new PdfTrueTypeFont(new Font("標楷體", 14, FontStyle.Bold), true), brush, rec);
            }


********************************************************************************
2020-06-30  補充

不要把 .PDF 當成是 .docx,如果換上去的文字很長,可能會和其他文字重疊顯示。
因為 .pdf 產生時,會明確定義文字或圖片呈現是格式和位置,其中某段落文字被更換後,其他段落文字位置不會因為某段落文字增加變長,下面的段落自動下移動,不會的,請把空間留夠。

********************************************************************************
2023-11-07 補充,關於左右對齊,實際測試失敗


PdfStringFormat format = new PdfStringFormat();
format.Alignment= PdfTextAlignment.Justify; // 只有 Center, Left, Right, Justify,實際測試 Justify 無法左右對齊
//string text = "這是您想要兩側對齊的文本。";
//page.Canvas.DrawString(text, font, PdfBrushes.Black, new RectangleF(100, 100, 400, 0), format);

page.Canvas.DrawRectangle(PdfBrushes.White, rec);
rec.Width = PdfPageSize.A4.Width - rec.X * 2;
rec.Height = rec.Y + 72;   // 72 是自己測試隨便放的值,高度夠就好。
//page.Canvas.DrawString(content, new PdfTrueTypeFont(new Font("微軟正黑體", 18, FontStyle.Bold), true), brush, rec);
page.Canvas.DrawString(content, new PdfTrueTypeFont(new Font("微軟正黑體", 18, FontStyle.Bold), true), brush, rec, format);


********************************************************************************
2021-08-26

FreeSpire.PDF 6.2.60 升級 FreeSpire.PDF 7.8.9 後,Visual Studio 2019 編譯出現警告

warning CS0618: 'PdfTextFind.Bounds' 已經過時: 'This property may be removed in the future, please use TextBounds instead.'

似乎是 NuGet 升級 PdfTextFind 版本的關係

PdfTextFind Class
Assembly: Spire.Pdf (in Spire.Pdf.dll) Version: 6.2.6.0 (6.2.6.2020)
https://www.e-iceblue.com/api_documents/5e4e0b69721393-11731598/res/html/d337da17-db94-256c-1fe8-b08d2796720c.htm

官方網頁說明依然 6.2.60 版,依然是用 Bounds,沒有 TextBounds 用法。找了一下

 rec = find.Bounds;

要改成

rec = find.TextBounds[0];
********************************************************************************
2024-05-01

FreeSpire.PDF 8.6.0 升級 FreeSpire.PDF 10.2.0 後,Visual Studio 2019 編譯出現警告
  • warning CS0618: 'PdfTextFindCollection' 已經過時: 'This class may be removed in the future.'
  • warning CS0618: 'PdfPageBase.FindText(string, TextFindParameter)' 已經過時: 'This method may be removed in the future, please use PdfTextFinder.Find(string text) instead.'
  • warning CS0618: 'PdfTextFind' 已經過時: 'This class may be removed in the future.'
  • warning CS0618: 'PdfTextFind.Bounds' 已經過時: 'This property may be removed in the future, please use TextBounds instead.'
參考

直接拿官方範例來用,但底下多加一行
textReplacer.ReplaceAllText(".NET Framework", "New Content");
textReplacer.ReplaceAllText("燒餅", "油條"); // 出錯了


不知是否因為替換的字是繁體中文字的關係? 或要做特別的處理。

待研究。

********************************************************************************

(完)

相關

[研究][C#][ASP.NET] 使用 Free Spire.PDF for NET v6.2.0 取代 .pdf 中的文字 (成功,要考慮文字重疊問題)

[研究][C#][ASP.NET]使用 Aspose.PDF v20.6.0 替換 .pdf 中文字 (評估版產生的 .pdf 會有紅字,商業版疑要不斷更新授權)

[研究][C#][ASP.NET] 使用 iText 7 取代 .pdf 中的文字 (失敗)

****************************************

[研究][C#][ASP.NET] 用 Aspose.Words for .NET v20.6.0 取代 .docx 中文字 (目前正常)

[研究][C#][ASP.NET] 使用 FreeSpire.Doc 7.11.0 取代 .docx 中的文字 (成敗未定)

[研究][C#][ASP.NET] 用 NPOI 替換 Word (.docx) 中的文字 (成敗未定)

****************************************

[研究][C#][ASP.NET] 使用 FreeSpire.Doc 7.11.0 把 .docx 轉成 .pdf (免費版只能轉前3頁)

[研究][C#][ASP.NET] 用 Aspose.Words for .NET v20.6.0 把 .docx 轉 .pdf

沒有留言:

張貼留言