Форум программистов, компьютерный форум, киберфорум
Наши страницы

C# для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Sparklz
0 / 0 / 0
Регистрация: 16.08.2015
Сообщений: 8
#1

Вывод математических формул в Word - C#/.NET 4.x

26.04.2017, 20:19. Просмотров 928. Ответов 18

Есть у меня расчетная программа для курсача, препод требует вывод отчета в WORD. Формулы в основном с корнями, дробями и степенями, не более того. Как выводить подобное программно в WORD, чтоб вставлялось, как если бы я эти формулы вручную в WORD ввёл? И вообще посоветуйте литературу по работе с WORD/EXCEL через C#.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.04.2017, 20:19
Я подобрал для вас темы с готовыми решениями и ответами на вопрос .NET 4.x Вывод математических формул в Word (C#):

Прорисовка математических формул на форме. - C#
Здраствуйте, можно ли нарисовать формулу, которая представляется строкой(string) на форме. Как это можно реализовать?. Может у кого есть...

Отображение математических формул в виде картинки - C#
Здравствуйте, помогите с проблемой. Никак не могу найти ничего путного для отображения математических формул (дроби, степени, квадратные...

.NET 4.x Составить код для вычисления математических формул - C#
Привет всем, помогите выполнить такое задание Я первое задание написал код, но когда надо было показать результат с генерировался...

Вывод формул на лист Excel - C#
Здравствуйте! Хорошего всем настроения! Вот пишу, а слёзы душат и капают... Второй день не могу справиться с выводом формул на лист...

Редактор математических формул - C#
Требуется написать текстовый редактор с возможностью ввода математических формул (интегралы, пределы и т.д.). Знаю C#. Подскажите как...

Считывание математических формул из RichTextBox - C#
Нужна небольшая идея по реализации. Логика примерно такая: в RichTextBox1 вводим, например, следующее выражение :...

18
ViterAlex
6276 / 3480 / 1065
Регистрация: 11.02.2013
Сообщений: 7,665
Завершенные тесты: 3
26.04.2017, 22:23 #2
Цитата Сообщение от Sparklz Посмотреть сообщение
препод требует вывод отчета в WORD
Если работа с OpenXml, тогда проще. Начни с этого. Если же препод потребует, чтобы и doc-формат поддерживался, тогда придётся его переубеждать
0
bozzly
4 / 4 / 1
Регистрация: 28.03.2015
Сообщений: 23
26.04.2017, 22:36 #3
ахах
0
Sparklz
0 / 0 / 0
Регистрация: 16.08.2015
Сообщений: 8
27.04.2017, 19:07  [ТС] #4
Мне просто нужен метод, который добавляет формулу, как в ворде. Неужели нету такого? Нагуглить не получилось!
0
Миниатюры
Вывод математических формул в Word  
Storm23
Эксперт .NETАвтор FAQ
5728 / 3463 / 1056
Регистрация: 11.01.2015
Сообщений: 4,587
Записей в блоге: 31
27.04.2017, 19:37 #5
Цитата Сообщение от Sparklz Посмотреть сообщение
Формулы в основном с корнями, дробями и степенями, не более того. Как выводить подобное программно в WORD
Для задания формулы нужно использовать LaTeX. Затем из LaTeX генерировать картинку, как здесь, и затем уже картинку вставлять в вордовский документ.
0
Sparklz
0 / 0 / 0
Регистрация: 16.08.2015
Сообщений: 8
27.04.2017, 20:14  [ТС] #6
И что, это единственный способ реализовать показ формулы? Неужели нельзя вставить формулу, как на скрине?
0
ViterAlex
6276 / 3480 / 1065
Регистрация: 11.02.2013
Сообщений: 7,665
Завершенные тесты: 3
27.04.2017, 22:19 #7
Sparklz, можно. Запиши создание формулы макросом и посмотри код. Там чёрт ногу сломит

Добавлено через 4 минуты
Visual Basic
1
2
3
4
5
6
7
8
9
10
Selection.TypeText Text:="x="
    Selection.OMaths(1).Functions.Add(Selection.Range, wdOMathFunctionFrac).Frac.Type = wdOMathFracBar 'Дробь
    Selection.TypeText Text:="-b"
    Selection.InsertSymbol CharacterNumber:=8723, Unicode:=True, Bias:=0 'плюс-минус
    Selection.OMaths(1).Functions.Add(Selection.Range, wdOMathFunctionRad).Rad.HideDeg = True 'знак радикала без степени
    Selection.TypeText Text:="b"
    Selection.OMaths(1).Functions.Add Range:=Selection.Range, Type:=wdOMathFunctionScrSup 'верхний индекс для степени
    Selection.TypeText Text:="b2"
    Selection.MoveRight Unit:=wdCharacter, Count:=1
    Selection.TypeText Text:="-4ac2a"
Добавлено через 56 секунд
Рефакторингом можно конечно причесать, но объектную модель нужно изучать очень глубоко.
1
Aael
393 / 296 / 133
Регистрация: 02.06.2016
Сообщений: 514
Завершенные тесты: 1
27.04.2017, 22:26 #8
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Sparklz, и все зависит от того как вы умеете пользоваться мышкой в водре, например, уравнение можно вставить в текстовом виде и преобразовать его в формулу, затем в профессиональный вид (это Linearize и BuildUp, см. OMath и OMaths на msdn):
C#
1
2
3
4
5
6
Word.Application app = new Word.Application() { Visible = true };
Word.Document doc = app.Documents.Add();
Word.Paragraph par = doc.Paragraphs.Add();
 
par.Range.Text = "x=(-b\u00b1\u221a(n&b^2-4ac))/2a";
doc.OMaths.Add(par.Range).OMaths.BuildUp();
* про все объекты эти omath и тд. лучше спрашивать в ветке vba на форуме, на c# перевести будет легко, т.к. объектная модель таже
2
ViterAlex
6276 / 3480 / 1065
Регистрация: 11.02.2013
Сообщений: 7,665
Завершенные тесты: 3
27.04.2017, 22:51 #9
Ну а если работаешь через OpenXml, тогда немного понятнее, хотя код не менее кудрявый:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
using DocumentFormat.OpenXml.Math;
using W = DocumentFormat.OpenXml.Wordprocessing;
using DocumentFormat.OpenXml;
 
namespace GeneratedCode
{
    public class GeneratedClass
    {
       //Абзац с формулой 
       // Creates an Paragraph instance and adds its children.
        public Paragraph GenerateParagraph()
        {
            Paragraph paragraph1 = new Paragraph();
 
            OfficeMath officeMath1 = new OfficeMath();
 
            Run run1 = new Run();
 
            W.RunProperties runProperties1 = new W.RunProperties();
            W.RunFonts runFonts1 = new W.RunFonts(){ Ascii = "Cambria Math", HighAnsi = "Cambria Math" };
 
            runProperties1.Append(runFonts1);
            Text text1 = new Text();
            text1.Text = "x=";
 
            run1.Append(runProperties1);
            run1.Append(text1);
 
            Fraction fraction1 = new Fraction();
 
            FractionProperties fractionProperties1 = new FractionProperties();
 
            ControlProperties controlProperties1 = new ControlProperties();
 
            W.RunProperties runProperties2 = new W.RunProperties();
            W.RunFonts runFonts2 = new W.RunFonts(){ Ascii = "Cambria Math", HighAnsi = "Cambria Math" };
            W.Italic italic1 = new W.Italic();
 
            runProperties2.Append(runFonts2);
            runProperties2.Append(italic1);
 
            controlProperties1.Append(runProperties2);
 
            fractionProperties1.Append(controlProperties1);
 
            Numerator numerator1 = new Numerator();
 
            Run run2 = new Run();
 
            W.RunProperties runProperties3 = new W.RunProperties();
            W.RunFonts runFonts3 = new W.RunFonts(){ Ascii = "Cambria Math", HighAnsi = "Cambria Math" };
 
            runProperties3.Append(runFonts3);
            Text text2 = new Text();
            text2.Text = "-b∓";
 
            run2.Append(runProperties3);
            run2.Append(text2);
 
            Radical radical1 = new Radical();
 
            RadicalProperties radicalProperties1 = new RadicalProperties();
            HideDegree hideDegree1 = new HideDegree(){ Val = BooleanValues.One };
 
            ControlProperties controlProperties2 = new ControlProperties();
 
            W.RunProperties runProperties4 = new W.RunProperties();
            W.RunFonts runFonts4 = new W.RunFonts(){ Ascii = "Cambria Math", HighAnsi = "Cambria Math" };
            W.Italic italic2 = new W.Italic();
 
            runProperties4.Append(runFonts4);
            runProperties4.Append(italic2);
 
            controlProperties2.Append(runProperties4);
 
            radicalProperties1.Append(hideDegree1);
            radicalProperties1.Append(controlProperties2);
            Degree degree1 = new Degree();
 
            Base base1 = new Base();
 
            Superscript superscript1 = new Superscript();
 
            SuperscriptProperties superscriptProperties1 = new SuperscriptProperties();
 
            ControlProperties controlProperties3 = new ControlProperties();
 
            W.RunProperties runProperties5 = new W.RunProperties();
            W.RunFonts runFonts5 = new W.RunFonts(){ Ascii = "Cambria Math", HighAnsi = "Cambria Math" };
            W.Italic italic3 = new W.Italic();
 
            runProperties5.Append(runFonts5);
            runProperties5.Append(italic3);
 
            controlProperties3.Append(runProperties5);
 
            superscriptProperties1.Append(controlProperties3);
 
            Base base2 = new Base();
 
            Run run3 = new Run();
 
            W.RunProperties runProperties6 = new W.RunProperties();
            W.RunFonts runFonts6 = new W.RunFonts(){ Ascii = "Cambria Math", HighAnsi = "Cambria Math" };
 
            runProperties6.Append(runFonts6);
            Text text3 = new Text();
            text3.Text = "b";
 
            run3.Append(runProperties6);
            run3.Append(text3);
 
            base2.Append(run3);
 
            SuperArgument superArgument1 = new SuperArgument();
 
            Run run4 = new Run();
 
            W.RunProperties runProperties7 = new W.RunProperties();
            W.RunFonts runFonts7 = new W.RunFonts(){ Ascii = "Cambria Math", HighAnsi = "Cambria Math" };
 
            runProperties7.Append(runFonts7);
            Text text4 = new Text();
            text4.Text = "2";
 
            run4.Append(runProperties7);
            run4.Append(text4);
 
            superArgument1.Append(run4);
 
            superscript1.Append(superscriptProperties1);
            superscript1.Append(base2);
            superscript1.Append(superArgument1);
 
            Run run5 = new Run();
 
            W.RunProperties runProperties8 = new W.RunProperties();
            W.RunFonts runFonts8 = new W.RunFonts(){ Ascii = "Cambria Math", HighAnsi = "Cambria Math" };
 
            runProperties8.Append(runFonts8);
            Text text5 = new Text();
            text5.Text = "-4ac";
 
            run5.Append(runProperties8);
            run5.Append(text5);
 
            base1.Append(superscript1);
            base1.Append(run5);
 
            radical1.Append(radicalProperties1);
            radical1.Append(degree1);
            radical1.Append(base1);
 
            numerator1.Append(run2);
            numerator1.Append(radical1);
 
            Denominator denominator1 = new Denominator();
 
            Run run6 = new Run();
 
            W.RunProperties runProperties9 = new W.RunProperties();
            W.RunFonts runFonts9 = new W.RunFonts(){ Ascii = "Cambria Math", HighAnsi = "Cambria Math" };
 
            runProperties9.Append(runFonts9);
            Text text6 = new Text();
            text6.Text = "2a";
 
            run6.Append(runProperties9);
            run6.Append(text6);
            W.BookmarkStart bookmarkStart1 = new W.BookmarkStart(){ Name = "_GoBack", Id = "0" };
            W.BookmarkEnd bookmarkEnd1 = new W.BookmarkEnd(){ Id = "0" };
 
            denominator1.Append(run6);
            denominator1.Append(bookmarkStart1);
            denominator1.Append(bookmarkEnd1);
 
            fraction1.Append(fractionProperties1);
            fraction1.Append(numerator1);
            fraction1.Append(denominator1);
 
            officeMath1.Append(run1);
            officeMath1.Append(fraction1);
 
            paragraph1.Append(officeMath1);
            return paragraph1;
        }
 
 
    }
}
0
Sparklz
0 / 0 / 0
Регистрация: 16.08.2015
Сообщений: 8
07.05.2017, 22:48  [ТС] #10
C#
1
2
3
4
5
6
7
8
9
Word.Application app = new Word.Application() { Visible = true };
            Word.Document doc = app.Documents.Add();
            Word.Paragraph par = doc.Paragraphs.Add();
       
            par.Range.Text = "x=(-b\u00b1\u221a(n&b^2-4ac))/2a";
            doc.OMaths.Add(par.Range).OMaths.BuildUp();
            
            Word.Paragraph par1 = doc.Paragraphs.Add();
            par1.Range.Text = "123";
А почему такой код пишет только 123 в ворде, не пойму, как работает эта модель и не кайф разбираться, просто подскажите еще: как новую строку в вашем варианте добавить, и чтоб она уже была обычной?
0
Aael
393 / 296 / 133
Регистрация: 02.06.2016
Сообщений: 514
Завершенные тесты: 1
08.05.2017, 01:43 #11
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Sparklz, не знаю, что конкретно возвращает Paragraphs.Add, в это случае она возвращает параграф перед вставляемым, который затирается новым текстом.
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
par = doc.Paragraphs.Last; // первый есть всегда
par.Range.Text = "x=(-b\u00b1\u221a(n&b^2-4ac))/2a";
doc.OMaths.Add(par.Range).OMaths.BuildUp();
 
doc.Paragraphs.Add();
par = doc.Paragraphs.Last;
par.Range.Text = "123";
 
doc.Paragraphs.Add();
par = doc.Paragraphs.Last;
par.Range.Text = "456";

Range - это низкоуровневый объект, над ним уже строятся остальные объекты Sentences, Paragraphs, итд.. Он содержит номера первого (Start) и последнего (End) символов. Умеет автоматически расширяться, например метод Range.InsertAfter(текст), добавит в конец диапазона (range) текст, расширив диапазон. Сам объект range можно получить указав номера символов начала и конца, либо позиционируясь по параграфам, таблицам, предложениям итд..

Есть еще один способ наполнения документа - через интерфейс Selection, он тормозной, но это не страшно. Можно расширить его методы, в зависимости от нужд, вставка таблиц, списков, текста с формулами (чтобы, как в latex отделять формулы Sel.TypeTextEx("Формула: $x^2$, текст")). Далее, получаем Range (например ячейку таблицы), выделяем методом Select, и используем Selection
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
static class Program
{
    static void TypeOMath(this Microsoft.Office.Interop.Word.Selection Selection, string Text, bool Inline = true)
    {
        int start = Selection.Range.End;
        Selection.TypeText(Text);
        int end = Selection.Range.End;
        Selection.TypeText("R");
 
        var textRange = Selection.Document.Range(start, end);
        var mathRange = Selection.OMaths.Add(textRange);
 
        mathRange.OMaths[1].BuildUp();
        mathRange.OMaths[1].Type = Inline ? 
            Word.WdOMathType.wdOMathInline : 
            Word.WdOMathType.wdOMathDisplay;
        
        Selection.TypeBackspace(); // стираем R (нужно, чтобы правильно ставился перенос строки в конце).
    }
 
    const char SquareRoot = '\u221a';
    const char Sigma = '\u2211';
    const char LLBracket = '\u3016'; // эти скобки не отображаются, но дают возможность делать группу
    const char RLBracket = '\u3017';
    const char Shade = '\u2592';
    const char Vec = '\u20d7';
    const char SmallDelta = '\u03b4';
 
    static void Main()
    {
        Word.Application app = new Word.Application() { Visible = true };
        Word.Document doc = app.Documents.Add(/* заранее подготовленный шаблон со стилями */);
 
        doc.Select();
        app.Selection.set_Style(Word.WdBuiltinStyle.wdStyleHeading1);
        app.Selection.TypeText("Бесполезный текст");
 
        app.Selection.TypeParagraph();
        app.Selection.set_Style(Word.WdBuiltinStyle.wdStyleHeading2);
        app.Selection.TypeText("Вариации второго основного тензора при ");
        app.Selection.TypeOMath("k");
        app.Selection.TypeText(" - движении");
 
        app.Selection.TypeParagraph();
        app.Selection.TypeText("Пусть поверхность ");
        app.Selection.TypeOMath("S");
        app.Selection.TypeText(" подвергнута ");
        app.Selection.TypeOMath("k");
        app.Selection.TypeText(" - движению");
        app.Selection.TypeOMath($"r{Vec}^t=r{Vec}+2{Sigma}^k_(l=1){Shade}t^l {SmallDelta}^(l-s) r{Vec}+o(t^k)", false);
        app.Selection.TypeText("тогда что-то точно произойдет.");
 
        app.Selection.TypeParagraph();
        app.Selection.set_Style(Word.WdBuiltinStyle.wdStyleHeading2);
        app.Selection.TypeText("Еще бесполезный текст ");
 
        app.Selection.TypeParagraph();
        app.Selection.TypeText("Корень ");
        app.Selection.TypeOMath($"{SquareRoot}(x&y)");
        app.Selection.TypeText(", чтобы был.");
    }
}
3
Sparklz
0 / 0 / 0
Регистрация: 16.08.2015
Сообщений: 8
10.05.2017, 11:24  [ТС] #12
Последний вопрос: откуда вы код для формулы взяли, чтоб ворд в такую формулу вывел? Где это можно глянуть?
В Гугле LateX, MathML искал, не подходит оно к этому.
0
Aael
393 / 296 / 133
Регистрация: 02.06.2016
Сообщений: 514
Завершенные тесты: 1
10.05.2017, 14:38 #13
Sparklz, набрал формулу в word привел к линейному формату (в контекстном меню формулы кнопка есть) и посмотрел, а так вот: Linear format equations and Math AutoCorrect in Word
2
Sparklz
0 / 0 / 0
Регистрация: 16.08.2015
Сообщений: 8
13.05.2017, 10:54  [ТС] #14
А как нижний индекс в тексте сделать, чтобы не на весь параграф было, а на конкретный символ? И можно ли вставить формулу в обычный текст, типо какой-то текст, а внутри формула?
0
Serg34
89 / 89 / 19
Регистрация: 20.09.2014
Сообщений: 411
Записей в блоге: 3
Завершенные тесты: 1
15.10.2017, 14:15 #15
Aael, Все работает, только таблицы после формулы не добавляются.

Текст ошибки: Метод или свойство недоступны, поскольку ее нельзя вызвать из математической области.

Причем между формулой и таблицей еще вставляется простой текст.

Вот код вставки формулы:
C#
1
2
3
4
5
6
7
8
9
10
11
internal static void AddOMaths(this Word._Document wordDoc, string text)
{
    object missing = System.Reflection.Missing.Value;
    wordDoc.Paragraphs.Add(ref missing);
    Word.Range wRng = wordDoc.Paragraphs.Last.Range;
 
    wRng.Text = text;
 
    var mathRange = wRng.OMaths.Add(wRng);
    mathRange.OMaths[1].BuildUp();  
}
Код вставки таблицы:
C#
1
2
3
4
5
6
7
8
9
10
11
internal static Word.Table AddTable(this Word._Document wordDoc, int rowCount, int columnCount)
{
    object missing = System.Reflection.Missing.Value;
    wordDoc.Paragraphs.Add(ref missing);
    Word.Range wRng = wordDoc.Paragraphs.Last.Range;
 
    object behavior = Word.WdDefaultTableBehavior.wdWord9TableBehavior;
    object autoFitBehavior = Word.WdAutoFitBehavior.wdAutoFitFixed;
 
    return wordDoc.Tables.Add(wRng, rowCount, columnCount, ref behavior, ref autoFitBehavior);
}
Что может быть не так?
0
15.10.2017, 14:15
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.10.2017, 14:15
Привет! Вот еще темы с ответами:

Реализация ввода формул как в Word - C#
Необходимо построить график функции по заданной функции (функция должна полность вводиться вручную). Хотел сделать как в ворде, акуратно и...

Программная вставка формул в Microsoft Word - C#
Доброго времени суток. Долго искал по гугле как вставить формулу в ворде, и после того как нашел появился другой вопрос. Как начать...

Вывод данных в word - C#
Добрый день. Существует проблема следующего характера: необходимо создать отчет в word, таким образом, чтобы данные располагались...

Вывод текста из Word в textBox1 - C#
Здраствуйте!!! Возможна ли вывод текста из Wordа в textBox1. Если да, то как? Подскажите пожалуйста!!! Заранее спасибо.


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru