Когда в разрабатываемом приложении нужно конвертировать, создавать или изменять файлы, приходится подключать для этого готовые решения — чтобы не погружаться в спецификации форматов. Таких решений много, в том числе для С#, но вот незадача: все они зарубежные. В нынешних условиях применять их может быть неудобно, а кому-то даже нельзя.
Я Максим Саутин из компании 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();
}
}
}
Как видите, строк кода минимум и всё довольно понятно и прозрачно.
В общем, если у вас в компании встал вопрос об импортозамещении, предлагаем попробовать наши библиотеки. На сайте можно потыкаться в демо и протестировать самим — в этом плане идем навстречу и даем пробовать продукт столько, сколько нужно. Ну и приходите с вопросами в комментарии — с радостью на них ответим.
Комментарии (60)
dopusteam
06.06.2023 09:58+7Как видите, строк кода минимум и всё довольно понятно и прозрачно.
Видим, что код нерабочий и даже не скомпилится. Это если не говорить про его оформление (точнее отсутствие).
А тесты у вас есть на всё это дело?
SautinMax Автор
06.06.2023 09:58-1Тут более 200 примеров кода на C#, чтобы охватить любые действия в ПО документами, все протестировано, компилится и работает:
Как создать DOCX документ на C# и VB.NET (sautinsoft.ru)
vilgeforce
06.06.2023 09:58+7Вы ведь правда про неотечественный .NET, работающий в неотечественной (чтобы там они ни придумывали) ОС, поверх неотечественных же библиотек?
SautinMax Автор
06.06.2023 09:58-4Ну тот же язык C#, и его прародители C, C++ тоже не в России, к сожалению, изобрели. Что имеем, на том и работаем, пусть изначально это "их" технологии, зато ПО наше, других технологий пока нет.
vilgeforce
06.06.2023 09:58+3Делать свое чтобы сделать свое - нет смысла, поскольку см. выше про неотечественность
SautinMax Автор
06.06.2023 09:58-1Смысл делать свое всегда есть. Если кто-то смог сделать, то если не сдаваться, стараться, то и мы сможем пусть даже на их языке.
sci_nov
06.06.2023 09:58Вообще, наверное, смысл в деньгах и знаниях (опыте), а так - наука, в т.ч. и программирование и прочая техника, не имеют отечества.
petelinsergey
06.06.2023 09:58+20В том технологическом стеке для которого вы предлагаете свои "импортозамещённые" библиотеки зарубежное всё, начиная с блока питания вашего десктопа и заканчивая каким-нибудь GitHub Extension for Visual Studio (а посредине между ними ещё несколько десятков тысяч компонент). Ваша неспособность увидеть очевидную абсурдность этой ситуации граничит с глупостью и более всего напоминает какой-то грёбаный цирк шапито. А вам, господа айтишники совет - если видите в тексте слово "импортозамещение", закрывайте страницу, бросайте свой гаджет максимально далеко вперёд, разворачивайтесь на 180 градусов и бегите так долго, как сможете. Только так у вас будет шанс сохранить хоть толику благоразумия. :)
SautinMax Автор
06.06.2023 09:58-2Все наши компоненты можно уже запустить на Linux: https://sautinsoft.ru/products/document/help/net/getting-started/using-in-linux.php, не привязываясь к Visual Studio и Microsoft.
vilgeforce
06.06.2023 09:58+5А Linux-то с каких пор стал отечественным?
SautinMax Автор
06.06.2023 09:58-2Отечественную ОС насколько я знаю на ядре Linux-а разрабатывают.
vilgeforce
06.06.2023 09:58+1Что вам тогда мешает считать Windows отечественной, да чего уж мелочиться, всю компанию Microsoft!
kahi4
06.06.2023 09:58+1Небольшая придирка, но у вас текстовая версия инструкции по ссылки на не совсем отечественном языке. (А, ну и видео тоже).
Ну и в инструкции указан vs code с extension, которые (тадам) Microsoft. Extensions, к слову, скачиваются с маркетплейса Микрософта тоже.
В общем, понятно что можно писать в vim (хмм, имя создателя которого Bram Moolenaar не очень похоже на каноническое славянское имя, наверное имеет французские корни) на астралинуксе, но это даже не смешно. Типа всё остальное ОК потому что опенсорс, а вот библиотека для pdf opensource не ок, импортозамещайте.
PDF, к слову, тож не особо русский.
panzerfaust
06.06.2023 09:58+4Российское решение сейчас выглядит более привлекательным
Даже если начать пилить его вчера, оно станет просто "нормальным" только после нескольких лет дебага, "привлекательным" после поддержки интероперабельности с теми же нехорошими западными продуктами, а "более привлекательным" после всемирного тренда на переход на новый формат.
Querion
06.06.2023 09:58+6У вас на сайте указано в контактах: "Sweden, Stockholm Mortviksvagen 68B 142 43 SKOGASSales & Support: Tel: +46 812111486". Статья для Шведов? Это у них нет библиотек?
SautinMax Автор
06.06.2023 09:58-3Смотрите координаты на нашем Российском сайте: https://sautinsoft.ru/about.php, там Россия, Удмуртская Республика, г. Воткинск. А шведский адрес на сайте sautinsoft.com.
Querion
06.06.2023 09:58+2Была интересна утилита, упомянутая в статье, вот и перешел по ссылке - https://sautinsoft.net/online-demo/pdf-focus/online-demo1.aspx
А там внизу Швеция. Вопрос возник сам собой.
Keeper9
06.06.2023 09:58+12Так вы определитесь уже -- вы российская компания, или шведская (члена НАТО, если что).
Уж не засланный ли казачок?
pewpew
06.06.2023 09:58+8А почему у вас комментарии на вражеском языке? Вы же топите за скрепность. Пишите на языке отечества.
SautinMax Автор
06.06.2023 09:58-4Я думаю все программисты и наши и их знают этот вражеский язык. Мы пишем код сразу на оба сайта .com и .ru. Знать чужой язык, это не значит не любить свою страну и свое Отечество.
freeExec
06.06.2023 09:58+2Так а нафига это нужно (PDF/DOCX) если это опять же под не русский софт, с которым тоже должны быть аналогичные проблемы как и с не русскими библиотеками. Пилите уже тогда по МойОфис чтоли.
SautinMax Автор
06.06.2023 09:58-1МойОфис, это программа с GUI интерфейсом, мы создаем SDK библиотеки, чтобы любой C# программист, мог в своем приложении создать новый документ, или загрузить PDF, DOCX, заполнить в нем формы, выполнить поиск и замену и т.д. Например, создавать электронные билеты в PDF, или на основе шаблона и БД, автоматически создавать однотипные договора и т.д.
stbear
06.06.2023 09:58+1Чем не устраивают MigraDoc, ClosedXML, NPOI?
SautinMax Автор
06.06.2023 09:58-3Да я не против использования бесплатного ПО как MigraDoc, но я думаю функционал у платного, раз он платное, должен быть мощнее и шире, ну а пользователь сам должен решить, что лучше. У нас можно тестировать нашу SDK SautinSoft.Document сколько угодно.
vitesse
06.06.2023 09:58+4Честно, я как украинец, наверное должен был бы тоже написать ироничный комментарий, но напишу серьёзный. Если одним из главных достоинств продукта ставится его происхождение, то вам стоит пересмотреть приоритеты, сделайте акцент на удобстве (тот же Aspose это боль, так как разные API используют разные контракты, нумерацию страниц то с 0, то с 1, и т.д., но лучше чем некоторые аналоги), скорости (снова таки Aspose течёт по памяти), поддержке различных особенностей разных форматов документов (вот тут Aspose сравнительно хорош), поддержка (вот тут, вероятно происхождение может быть плюсом, так как проще вести диалог, но он как по мне слишком незначительный), скорость закрытия багов, документация (качество и отставание от реальности). Вот если по разным критериям, ваш продукт "догонит" или "перегонит" конкурентов, им будут пользоваться. Ну или если пока "не догоняет", то напишите, что вам нужна помощь в поддержке отечественной компании. Проблема современного мира в том, что мы сильно зависим от других людей и стран в том числе, и ограждаться от всех бесполезно - это как делать "домашний" майонез, колбасу или ещё что-то из покупных продуктов, телефоны и прочую электронику из китайских деталей. Не нужно делать культ из того, кем что-то сделано, лучше сфокусироваться на реальных достоинствах продукта - майонез вкуснее и без добавок, телефон быстрее и меньше разряжается и т.д.
ost-vld
06.06.2023 09:58А вы пытались свою .Net на отечественных линуксах (Астра, Alt) запустить? Какой смысл в отечественном по на С#, если его не получится использовать?
s207883
06.06.2023 09:58А в чем разница? Мы на RedOs запускали наше приложение, с астрой и альтом скорее всего будет тоже самое, главное библиотеки .net закинуть.
HemulGM
Т.е. вы предлагаете заменить бесплатные и свободные библиотеки с открытым исходным кодом на закрытые и платные?
И о каком "импортозамещении" может идти речь, если вы используете .NET
sci_nov
На сайте довольно-таки позитивно всё: клиенты, доверие и т.п. Значит это кому-то надо )
c_kotik
Для галочки "импортозамщено" по другому быть и не может.
sci_nov
Да-к 20 лет занимаются, когда активного замещения еще не было.
HemulGM
Сам MS их библиотеками пользуется!
sci_nov
Взаимное влияние никто не отменял :)
SautinMax Автор
Да, в 2017 они купили нашу библиотеку - PDF Metamorphosis .Net.
k-semenenkov
Скажите, вы в трастед бай просто по факту заказа добавляете или согласовываете это с клиентом?
SautinMax Автор
Логотипы с клиентами мы не согласовываем, если покупали, и имя известное, то их логотип выставляем на страничке "наши клиенты". Бывает, что они в переписке оставляют отзывы - testimonials, когда например мы ошибку исправили оперативно и выслали update. Тут спрашиваем, можно ли разместить его отзыв о нас, если отзыв позитивный :)
k-semenenkov
Насколько я знаю, это сильно неверный подход. То что компания купила продукт это не значит что она готова его рекламировать своим именем.
У меня как-то одна очень известная гейм-студия несколько лет подряд покупала лицензии (т.е. явно положительный опыт использования), я после очередного заказа спросил насчет включить их в трастед бай - был где то месяц утряски этого вопроса с их легал департмент и в итоге ответ отрицательный.
kahi4
В Microsoft просто орава народа, которые используют (пробуют) разные продукты. В итоге каждая вторая библиотека в мире имеет "нас использует сам Микрософт!".
Не удивлюсь если какая-то R&D команда купила вашу библиотеку потыкать и потестировать производительность или что-то еще и затем закрыла на полке. В конце концов, они проверяют как их изменения влияют на зависимые библиотеки, как разработчики самого .net.
M_AJ
Вы уверены, что по адресу 6820 Harl Ave в Аризоне расположена компания Microsoft? И вообще, разве компании оплачивают счета от имени физических лиц?
SautinMax Автор
Обычно перед покупкой клиенты пишут, например с вопросами какую лицензию им выбрать или присылают тестовые файлы, если что-то не работает. Да, мы уверены, если переписка идет с адреса ...@micosoft.com. В этом нет ничего такого необычного, что такие крупные компании покупают софт у маленьких компаний.
fedorro
Да, счастье не будет полным пока не будет работать на отечественном .НЕТъ или .СЕТь под отечественными ОС-ами.
SautinMax Автор
Да, мы используем .NET, но он сейчас полностью создан с открытым исходным кодом: https://github.com/dotnet/runtime. Мы предлагаем инструменты для работы с PDF и DOCX полностью написанные в России, с поддержкой здесь, в России. Есть много платных иностранных аналогов, например Aspose или PDF Tron, они ушли из России, мы наооборот предлагаем альтернативу им, потому как знаем их давно, и конкурируем с ними.
grebenval
О самом настоящем. Смотрите требования на сайте РЕЕСТР РОССИЙСКОГО ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ https://reestr.digital.gov.ru/. Критерии российского ПО, определены однозначно.
SautinMax Автор
Так мы же и находимся в Реестре Отечественного ПО: SautinSoft.Document (digital.gov.ru)
MonkAlex
Я не в курсе, поэтому просто уточнить хочу - какие открытые продукты умеют работать с docx хорошо? И с pdf, если есть возможность.
Упомянутый в статье аспоз - закрытый и платный. Что-то там для пдф искали в своё время на работе - бесплатное было очень среднего качества.
Другое дело, без понятия как дела у рекламируемого продукта, тестировать нужно на реальных документах.
SautinMax Автор
Косяки есть в любом ПО, у нас есть тестовые файлы от клиентов на которых глючит Word. Aspose крупная компания, их ПО известно по всему миру, и в том числе и у нас в России. Однако у нас есть клиенты, которые перешли от них к нам, по качеству мы оказались не хуже. Мы кстати ведем тесты часто сравниваем нас с конкурентами на определенных наборах файлов.