c# 文件在线预览功能

 

using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;

using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using OfficeOpenXml;
using System;
using System.Data;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using HtmlAgilityPack;
using DocumentFormat.OpenXml;
using System.Text;

namespace FilePreview.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class PreviewController : ControllerBase
    {
        static PreviewController()
        {
            ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
        }

        /// <summary>
        /// 预览Excel
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> PreviewExcel(string filePath)
        {
            //需要安装一个名为"EPPlus"的NuGet包
            try
            {
                using (ExcelPackage excelPackage = new ExcelPackage(new FileInfo(filePath)))
                {
                    DataSet dataSet = new DataSet();

                    foreach (ExcelWorksheet worksheet in excelPackage.Workbook.Worksheets)
                    {
                        System.Data.DataTable dataTable = new System.Data.DataTable(worksheet.Name);
                        for (int col = 1; col <= worksheet.Dimension.Columns; col++)
                        {
                            string columnName = worksheet.Cells[1, col].Value?.ToString();
                            dataTable.Columns.Add(columnName);
                        }
                        for (int row = 2; row <= worksheet.Dimension.Rows; row++)
                        {
                            DataRow dataRow = dataTable.NewRow();
                            for (int col = 1; col <= worksheet.Dimension.Columns; col++)
                            {
                                object cellValue = worksheet.Cells[row, col].Value;
                                dataRow[col - 1] = cellValue;
                            }
                            dataTable.Rows.Add(dataRow);
                        }
                        dataSet.Tables.Add(dataTable);
                    }
                    string json = JsonConvert.SerializeObject(dataSet);
                    return Ok(json);
                }
            }
            catch (System.Exception ex)
            {
                return Ok(ex.Message);
            }

        }


        /// <summary>
        /// 预览word
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> PreviewWord(string filePath)
        {
            //需要安装一个名为"Open XML SDK"的NuGet包
            try
            {
                // 打开 Word 文档
                using (WordprocessingDocument doc = WordprocessingDocument.Open(filePath, false))
                {
                    // 获取文档主体部分
                    MainDocumentPart mainPart = doc.MainDocumentPart;
                    Document document = mainPart.Document;
                    Body body = document.Body;

                    string html = "<html><body>";
                    // 遍历文档中的所有段落
                    foreach (OpenXmlElement element in body.Elements())
                    {
                        switch (element)
                        {
                            case Paragraph paragraph:
                                html += ConvertParagraphToHtml(paragraph, mainPart);
                                break;
                            case Table table:
                                html += ConvertTableToHtml(table);
                                break;
                        }
                    }

                    //foreach (Paragraph paragraph in body.Elements<Paragraph>())
                    //{
                    //    // 将段落转换为 HTML
                    //    string paragraphHtml = ConvertParagraphToHtml(paragraph, mainPart);

                    //    // 添加段落 HTML 到总体 HTML 字符串中
                    //    html += paragraphHtml;
                    //}

                    html += "</body></html>";

                    return Ok(html);
                }
            }
            catch (System.Exception ex)
            {
                return Ok(ex.Message);
            }
        }
        private static string ConvertParagraphToHtml(Paragraph paragraph, MainDocumentPart mainPart)
        {
            string html = "<p>";

            // 遍历段落中的所有运行
            foreach (Run run in paragraph.Elements<Run>())
            {
                // 遍历运行中的所有图片
                foreach (Drawing drawing in run.Elements<Drawing>())
                {
                    // 获取图片的嵌入对象
                    DocumentFormat.OpenXml.Drawing.Blip blip = drawing.Descendants<DocumentFormat.OpenXml.Drawing.Blip>().FirstOrDefault();
                    if (blip != null)
                    {
                        // 获取图片的 ID
                        string imageId = blip.Embed.Value;

                        // 获取与图片关联的图像部分
                        ImagePart imagePart = (ImagePart)mainPart.GetPartById(imageId);

                        // 将图像部分的内容转换为 Base64 字符串
                        string base64String = ConvertImagePartToBase64(imagePart);

                        // 构建 <img> 标签
                        string imgTag = $"<img src=\"data:image/png;base64,{base64String}\" alt=\"Image\" />";

                        // 添加到段落 HTML 中
                        html += imgTag;
                    }
                }

                // 获取运行的文本内容
                //string text = run.InnerText;

                string text = ConvertWordXmlToHtml(run.InnerText, run.InnerXml);
                // 添加文本内容到段落 HTML 中
                html += text;
            }

            html += "</p>";

            return html;
        }
        private static string ConvertImagePartToBase64(ImagePart imagePart)
        {
            using (Stream stream = imagePart.GetStream())
            {
                using (MemoryStream memoryStream = new MemoryStream())
                {
                    stream.CopyTo(memoryStream);
                    byte[] imageBytes = memoryStream.ToArray();
                    return Convert.ToBase64String(imageBytes);
                }
            }
        }
        public static string ConvertWordXmlToHtml(string text, string wordXml)
        {
            // 创建 HTML 文档对象
            HtmlDocument htmlDoc = new HtmlDocument();
            htmlDoc.OptionAutoCloseOnEnd = true;

            // 创建 <span> 元素并设置样式
            var spanNode = htmlDoc.CreateElement("span");

            var family = Substr(wordXml, "w:ascii=\"");
            var size = "12";
            int number;
            if (int.TryParse(Substr(wordXml, "w:val=\""), out number))
            {
                size = (int.Parse(Substr(wordXml, "w:val=\"")) / 2).ToString();
            }
            var style = "font-family: " + family + "; font-size: " + size + "px;";
            spanNode.SetAttributeValue("style", style);

            // 将文本内容添加到 <span> 元素中
            var textNode = htmlDoc.CreateTextNode(text);
            spanNode.AppendChild(textNode);

            // 将 <span> 元素添加到 HTML 文档中
            htmlDoc.DocumentNode.AppendChild(spanNode);

            // 将 HTML 文档转换为字符串
            using (var writer = new System.IO.StringWriter())
            {
                htmlDoc.Save(writer);
                return writer.ToString();
            }
        }
        public static string Substr(string originalString, string substring)
        {
            // 查找子字符串的索引
            int startIndex = originalString.IndexOf(substring);

            if (startIndex != -1)
            {
                // 截取子字符串后的一部分字符串
                string remainingString = originalString.Substring(startIndex + substring.Length);

                // 查找第一个引号的索引
                int endIndex = remainingString.IndexOf('"');

                if (endIndex != -1)
                {
                    // 利用 Substring 方法截取第一个引号之前的值
                    string result = remainingString.Substring(0, endIndex);
                    return result;
                }
            }
            return "";
        }
        private static string ConvertTableToHtml(Table table)
        {
            StringBuilder htmlBuilder = new StringBuilder();
            htmlBuilder.AppendLine("<table style=\"border-collapse: collapse;\">");
            foreach (TableRow row in table.Elements<TableRow>())
            {
                htmlBuilder.AppendLine("<tr>");
                foreach (TableCell cell in row.Elements<TableCell>())
                {
                    htmlBuilder.AppendLine("<td style=\"border: 1px solid black;\">");
                    foreach (Paragraph paragraph in cell.Elements<Paragraph>())
                    {
                        foreach (Run run in paragraph.Elements<Run>())
                        {
                            htmlBuilder.AppendLine(run.InnerText);
                        }
                    }
                    htmlBuilder.AppendLine("</td>");
                }
                htmlBuilder.AppendLine("</tr>");
            }
            htmlBuilder.AppendLine("</table>");
            return htmlBuilder.ToString();
        }
    }
}

 

 

方法调用

Excel文件预览:https://localhost:44368/api/Preview/PreviewExcel?filePath=C:\Users\Administrator\Desktop\001.xlsx
返回一个json结构的dataset 

Word文件预览:https://localhost:44368/api/Preview/PreviewWord?filePath=C:\Users\Administrator\Desktop\002.docx
返回一个前端的html页面

 

posted @ 2023-07-20 15:49  风中起舞  阅读(931)  评论(0编辑  收藏  举报