iT邦幫忙

0

asp.net webform如何將odt檔轉成PDF檔?

  • 分享至 

  • xImage

這是C# asp.net webform,目前要將odt檔轉成PDF檔下載,一直轉不成功,才來發問請教各位要怎麼改法?
謝謝

以下是目前的程式碼

Default.aspx.cs

protected void gvIndex_RowCommand(object sender, GridViewCommandEventArgs e)
{
OdtWriter wr = new OdtWriter();
string TemplatePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "App_Code/CSV/申請表.odt");             

Dictionary<string, string> values = new Dictionary<string, string>()
{
//資料內容省略
};

System.IO.MemoryStream memoryStream = new System.IO.MemoryStream();
wr.WriteOdtFile(values, TemplatePath, memoryStream);
byte[] filebytes = memoryStream.ToArray();
string filename = HttpUtility.UrlEncode("申請表.odt", Encoding.UTF8);
Response.AddHeader("Content-Disposition", string.Format("attachment; filename=" + filename));
Response.Charset = "big5";
Response.ContentType = "odt,application/vnd.oasis.opendocument.text";
Response.BinaryWrite(filebytes);
Response.Flush();
Response.End();
}

odtwriter.cs

public class OdtWriter
{
    // Read zip stream (.ods file is zip file).
private ZipFile GetZipFile(Stream stream)
        {
            return ZipFile.Read(stream);
        }

        // Read zip file (.ods file is zip file).
private ZipFile GetZipFile(string inputFilePath)
        {
            return ZipFile.Read(inputFilePath);
        }

private XmlDocument GetContentXmlFile(ZipFile zipFile)
        {
            // Get file(in zip archive) that contains data ("content.xml").
            ZipEntry contentZipEntry = zipFile["content.xml"];

            Stream contentStream = new MemoryStream();
            contentZipEntry.Extract(contentStream);
            contentStream.Seek(0, SeekOrigin.Begin);

            XmlDocument contentXml = new XmlDocument();
            contentXml.Load(contentStream);

            return contentXml;
        }

public void WriteOdtFile(Dictionary<string, string> values, string templatePath, Stream outputStream)
        {
            foreach (var key in values.Keys.ToList())
            {
                if (values[key] != null)
                values[key] = Regex.Replace(values[key], "[\x00-\x08\x0B\x0C\x0E-\x1F]", "");
            }

            ZipFile templateFile = this.GetZipFile(templatePath);

            XmlDocument contentXml = this.GetContentXmlFile(templateFile);

            foreach (XmlNode child in contentXml.ChildNodes)
                ReplaceValues(child, values);

            this.SaveContentXml(templateFile, contentXml);
            templateFile.Save(outputStream);
        }

public static void ReplaceValues(XmlNode node, Dictionary<string, string> values)
        {
            if (!string.IsNullOrEmpty(node.Value))
                node.Value = ReplaceCell(node.Value, values);
            foreach (XmlNode child in node.ChildNodes)
                ReplaceValues(child, values);
        }

private static Regex reg_Cell = new Regex("\\{\\{(?<key>.*?)\\}\\}", RegexOptions.Singleline | RegexOptions.IgnoreCase);
        
public static string ReplaceCell(string str, Dictionary<string, string> values)
        {
            foreach (Match match in reg_Cell.Matches(str))
            {
                var value = match.Value;
                var key = match.Groups["key"].ToString().Trim();
                if (values.ContainsKey(key))
                    str = str.Replace(value, values[key]);
            }
            return str;
        }

private void SaveContentXml(ZipFile templateFile, XmlDocument contentXml)
        {
            templateFile.RemoveEntry("content.xml");

            MemoryStream memStream = new MemoryStream();
            contentXml.InnerXml = contentXml.InnerXml.Replace("AssistanceTitle", "3. 您想要");
            contentXml.InnerXml = contentXml.InnerXml.Replace("ProductTitle", "4. 您要");
            contentXml.Save(memStream);
            memStream.Seek(0, SeekOrigin.Begin);

            templateFile.AddEntry("content.xml", memStream);
        }
    }
canrong iT邦新手 3 級 ‧ 2022-07-05 23:19:37 檢舉
沒看到pdf轉換邏輯,每個副檔名都有自己的讀取格式,不是只有改變副檔名就完事了。
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
2
科科
iT邦研究生 1 級 ‧ 2022-07-05 18:24:21

程式碼太長很少有人會耐心看,而且也沒說轉不成功是哪裡出現問題。

是有錯誤訊息? 還是沒有反應之類的?

那我只看 Response 那段,要回傳PDF,ContentType是否應該設為這樣

Response.ContentType = "Application/pdf";

另外 odt檔轉成PDF google應該有不少解法。

轉不成功的錯誤,主要是檔案下載後開啟會提示編碼錯誤

你建議的方式,contentType,已經有改過”Application/pdf",還是一樣會提示編碼問題

0

如果您的申請表,不會很複雜的話,
個人建議 ReportViwer 方案,可以用 RDLC 檔案畫線套變數,將 RDLC 的變數取代您想要的值,
然後再用 ReportViwer 內建的功能,轉成 PDF 檔案供使用者下載。

https://dotblogs.com.tw/shadow/2014/02/09/143891
HTML to PDF,說不定是更好的選擇。
不需要安裝任何 Office 軟體及套件,保證純。

0
淺水員
iT邦大師 6 級 ‧ 2022-07-05 22:25:09

不知道是不是我誤會你程式碼的意思
你是打算用取代的方式把 XML 結構轉成 PDF 嗎?
如果是的話我可以說這兩者無法這樣直接轉換的

開發過程中,你應該先試著把你產生的結果存在某個檔案(副檔名 pdf)
先自己打開看看產生的結果對不對
當這階段正確再考慮不另存檔案直接輸出

0
海綿寶寶
iT邦大神 1 級 ‧ 2022-07-06 09:28:18

Google 了半天
只能找到這篇比較接近
有空不妨試試看

我要發表回答

立即登入回答