Как стать автором
Обновить

Работа с файлами в приложениях: как уйти от зарубежных .NET-библиотек

Время на прочтение11 мин
Количество просмотров8.6K

Когда в разрабатываемом приложении нужно конвертировать, создавать или изменять файлы, приходится подключать для этого готовые решения — чтобы не погружаться в спецификации форматов. Таких решений много, в том числе для С#, но вот незадача: все они зарубежные. В нынешних условиях применять их может быть неудобно, а кому-то даже нельзя.

Я Максим Саутин из компании SautinSoft. Хочу порассуждать, почему в России не было собственных разработок в этом направлении, и рассказать, как работают наши .NET-библиотеки, которые используются на российском рынке. 

В чем проблема с созданием документов

Если вы откроете свойства любого PDF-документа, вы увидите, с помощью какого инструмента он был создан. Этих инструментов очень ограниченное число, и их все объединяет один факт: они зарубежные. 

Вот как выглядит инструмент в свойствах файла. Это как раз один из популярных зарубежных поставщиков решений для работы с документами

Если говорить конкретно о библиотеках для C#, их не так много, и все они тоже не российские — это инструменты от Aspose, iText, iTextSharp, Oracle, Microsoft. То же касается и других форматов: DOCX, HTML, RTF, XML. Все они создаются иностранными средствами, и даже у вас в проекте, если есть нужда работать с документами, наверняка используются зарубежные библиотеки.

Вообще подобных инструментов не так много по понятной причине: спецификация PDF и DOCX невероятно сложная. В PDF всё состоит из отдельных символов и объектов, причем каждый символ описан в специальной структуре, где хранятся его характеристики: цвет, шрифт, размерность и т. д. Все эти данные логически связаны, но находятся в разных местах документа. Это можно представить в виде запутанного клубка или лабиринта со множеством ответвлений. На Хабре как-то была про это статья, из которой еще больше понятно, почему разобраться в PDF — задача совсем нетривиальная. А чтобы с ними работать, придется написать десятки тысяч строк кода и потратить огромное количество времени на изучение спецификации.

DOCX немного проще, но и его парсинг достаточно запутанный. У него много пробелов в документации, так что приходится всё проверять и тестировать множество раз на сотнях исходных документов. Только так можно избежать смещения символов и картинок, поломок таблиц и тысячи других проблем.

Совершенно логично, что с нуля свои инструменты для работы с документами почти никто не пишет — ведь существуют готовые библиотеки. Но вот с тем, что все они зарубежные, сейчас возникли проблемы. Раньше готовые решения всех устраивали, поэтому разработчики из России не стремились написать свои библиотеки. Теперь всё сложнее. Крупным (а особенно государственным) компаниям приходится искать российские аналоги в связи с импортозамещением. Другим это вроде бы не обязательно, но всегда остаются проблемы с оплатой лицензий, риск прекращения техподдержки и другие сложности. 

Российское решение сейчас выглядит более привлекательным, но загвоздка в том, что его нет. Ну точнее, не было. И быстро оно не появится, так как закопаться во все эти спецификации и сделать что-то работающее — вопрос не одного года разработки. Мы проверяли =)

Какой выход есть из этой ситуации

В общем-то, выход простой: наши .NET-библиотеки. Мы разрабатываем их больше 20 лет, долгое время продавали на международный рынок, теперь концентрируемся на российском. Сейчас они включены в российский реестр программного обеспечения, так что ими могут пользоваться компании с требованиями к импортозамещению.

С помощью них можно:

  • Конвертировать документы между собой. Например, DOCX в PDF и обратно.

  • Выполнять любые операции с документами в форматах DOCX, PDF, RTF, HTML и TEXT: создавать, редактировать, добавлять картинки, схемы, таблицы и всё что нужно.

  • Создавать отчеты, подписывать документы цифровыми подписями, использовать MailMerge-слияния.

Всё стандартно: подключаете библиотеку к себе в C#-проект и работаете с документами, не закапываясь в их спецификации. 

Почти всё можно протестировать онлайн — например, вот тут лежит утилита для конвертации PDF в любые другие форматы. Это для понимания того, какой именно результат выдают наши конвертеры.

Из дополнительного прикольного мы как отечественные разработчики можем дать:

  • Плотное общение и быстрые обновления. Мы в принципе каждый месяц добавляем новые функции, в том числе часто по просьбам пользователей. Если в нашей DLL чего-то не хватает, разберемся, и если это возможно — добавим без проблем.

  • Специфические для России задачи. У нас конвертеры нормально работают со всеми кириллическими символами =) А если вам понадобится составлять документы, например, на башкирском — найдем тут башкира и добавим такую функцию. 

Теперь давайте посмотрим чуть поглубже, как у нас это всё работает.

Как всё это работает

Код библиотек написан полностью (standalone) на C# и платформе .NET. Мы начинали над ними работать в 2001-м, и тогда писали на С и С++, но с выходом C# полностью перешли на него. 

Библиотека весит 7 МБ, работает на любых операционных системах и поддерживает любые версии .NET, в том числе .NET Framework (4.6.1 и выше). Библиотеки полностью автономные, и зависимостей от Adobe Acrobat или Word у них нет, то есть можно пользоваться библиотекой там, где не стоят эти программы.

В плане подключения в код тоже всё максимально просто: нужно скопировать файл SautinSoft.Document.dll в папку с вашим приложением и добавить ссылку на него. Либо установить компонент через NuGet. Дальше подключить пространство имен, например, на C#:

using SautinSoft.Document

На VB.NET или F# библиотеки, конечно, тоже работают:
Imports SautinSoft.Document

Основной движок наших библиотек — SautinSoft.Document. По структуре он во многом похож на Microsoft Word, только для разработчиков. В документации можно посмотреть его структуру. Основная модель выглядит так:

Используя компонент, разработчик оперирует такими понятиями, как: 

  • документ (DocumentCore); 

  • раздел (Section); 

  • параграф (Paragraph); 

  • текст (Run); 

  • таблица (Table). 

Он может создать документ с нуля, добавить туда разделы, параграфы с текстом и форматированием. Потом сохранить его в любой из 5 форматов: DOCX, PDF, RTF, HTML, Изображение. Либо загрузить уже существующий документ и работать через модель документа (DOM), удалять, заменять, осуществлять поиск и замену текста, параграфов, удалять страницы, объединять документы — вообще всё, что душе угодно. Всё, что доступно в Microsoft Word, доступно и в SautinSoft.Document.

Сами команды, доступные в библиотеках, собраны в документации. В целом там всё просто: достаточно написать несколько строк кода, чтобы открыть документ и пересохранить его в другой формат. Все функции простые: загрузить, сохранить, добавить таблицу 5 на 5. Знания C# нужны минимальные, особенно для базовых операций. Для создания сложных многокомпонентных документов придется покопаться, но в целом логика работы такая же, как у других подобных библиотек, — переключиться можно быстро.

Для примера — вот как с помощью библиотеки можно найти в PDF все изображения и заменить их на другие:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using SautinSoft.Document;

using SautinSoft.Document.Drawing;

using SautinSoft.Document.Tables;

using System.IO;

namespace Example

{

    class Program

    {

        static void Main(string[] args)

        {

            ReplaceImagesInPdf();

        }

        /// <summary>

        /// How to replace images in PDF document.

        /// </summary>

        /// <remarks>

        /// Details: https://www.sautinsoft.com/products/document/help/net/developer-guide/from-customers-replace-images-in-pdf-in-csharp-vb-net.php

        /// </remarks>

        static void ReplaceImagesInPdf()

        {

            // Path to a loadable document.

            string loadPath = @"......\example.pdf";

            string pictPath = @"......\replaceNA.jpg";

            // Load a document intoDocumentCore.

            DocumentCore dc = DocumentCore.Load(loadPath);

            

            // Load the Picture from a file.

            Picture picture = new Picture(dc, InlineLayout.Inline(new Size()), pictPath);

            

            // Find all pictures in the document.

            foreach (Element el in dc.GetChildElements(true, ElementType.Picture).Reverse())

            {

                if (el is Picture)

                {

                    // Copy all properties of the found picture and assign these properties to the new picture.

                    // If you do not do this, the picture may be inserted into an arbitrary place in the document. 

                    if (((Picture)el).Layout is FloatingLayout)

                    {

                        FloatingLayout old = (FloatingLayout )((Picture)el).Layout;

                        picture.Layout = FloatingLayout.Floating(old.HorizontalPosition, old.VerticalPosition, old.Size);

                    }

                    // Replace picture.

                    el.Content.Replace(picture.Content);

                }

            }

            // Save our document into PDF format.

            string savePath = @"replaced.pdf";

            dc.Save(savePath);

            // Open the result for demonstration purposes.

            System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(loadPath) { UseShellExecute = true });

            System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(savePath) { UseShellExecute = true });

        }

    }

}

А вот как можно настроить поиск по документу по ключевому слову: в нашем случае это «Invoice»:

using SautinSoft.Document;

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Text.RegularExpressions;

using System.Threading.Tasks;

using System.Xml.Linq;

namespace Sample

{

    class Program

    {

        static void Main(string[] args)

        {

            FindPagesSpecifiedText();       

        }

        /// <summary>

        /// How to find out on which pages of the document the required word is located.

        /// </summary>

        /// <remarks>

        /// Details: https://sautinsoft.com/products/document/help/net/developer-guide/from-customers-find-pages-with-specified-text-net-csharp-vb.php

        /// </remarks>

        public static void FindPagesSpecifiedText()

        {

            // The path for input files or directory.

            string inpFile = @"......\example.docx";

            // What we need to search.

            var searchText = "Invoice";

            int quantity = 0;

            

            // Load our document in Document's engine.

            DocumentCore dc = DocumentCore.Load(inpFile);

            

            // Regex https://en.wikipedia.org/wiki/Regular_expression

            Regex regex = new Regex(searchText, RegexOptions.IgnoreCase);

            // Document paginator allows you to calculate of pages.

            DocumentPaginator dp = dc.GetPaginator();

            

            // We will search "searchText" on each pages (enumeration).

            for (int page = 0; page < dp.Pages.Count; page++)

            {

                foreach (ContentRange item in dp.Pages[page].Content.Find(regex).Reverse())

                {

                    Console.WriteLine({searchText}] on the page # {page +1}");

                    quantity++;

                }

            }

            Console.WriteLine();

            Console.WriteLine(" class="formula inline">"I met [{searchText}] {quantity} times.  Please click on any button");

            Console.ReadKey();

        }

    }

}

Как видите, строк кода минимум и всё довольно понятно и прозрачно.

В общем, если у вас в компании встал вопрос об импортозамещении, предлагаем попробовать наши библиотеки. На сайте можно потыкаться в демо и протестировать самим — в этом плане идем навстречу и даем пробовать продукт столько, сколько нужно. Ну и приходите с вопросами в комментарии — с радостью на них ответим.

Теги:
Хабы:
Всего голосов 38: ↑7 и ↓31-23
Комментарии85

Публикации

Истории

Работа

Ближайшие события

19 сентября
CDI Conf 2024
Москва
24 сентября
Конференция Fin.Bot 2024
МоскваОнлайн
30 сентября – 1 октября
Конференция фронтенд-разработчиков FrontendConf 2024
МоскваОнлайн