Не ясно почему были убрана метка "
Программирование" из вопроса. Получается ответ в некотором роде будет оффтопом.
Теперь по существу:
Не знаю если такая возможность
в Word, но если есть, то лучше (быстрее) будет воспользоваться именно ей.
Но если нужна именно программа, то я бы начал с составления ТЗ (технического задания), в котором было бы подробное описание требуемого функционала.
Пока описание в вопросе довольно расплывчатое, но вот набросок который на скорую руку написал за пару часов на языке программирования F#:
Примечание: Возможно F# не самый лучший выбор для данной задачи, но так как для своих персональных программ использую его, то и код привожу на нем.
1. Определяются основные объекты (Студент, Преподаватель, Абитуриент) для которых в виде свойств перечисляются характеристики для заполнения:
module Model
type Student = {
Name : string
Surname : string
LastName : string
Phone : string
Faculty : string
}
Отдельно, для удобства, представляем наши записи в виде размеченного объединения:
[<RequireQualifiedAccess>]
type AccountType =
| Student of Student
| Enrollee of Enrollee
| Teacher of Teacher
Создаем модуль
Defaults в котором будут находится значения по умолчанию для объектов (будет нужно для отображения):
[<RequireQualifiedAccess>]
module Defaults =
let student:Student = {
Name = ""
Surname = ""
LastName = ""
Phone = ""
Faculty = ""
}
Следующий шаг - создание или редактирование / заполнение готового Word или Pdf шаблона данными.
Есть несколько вариантов (библиотек) для работы и с тем и с другим форматом. Для Pdf есть очень известная библиотека:
iTextSharp
Есть и другие, как например,
SharpLayout
Документация в которой оставляет желать лучшего, но по крайней мере понятно что у нее нет проблем с отображением символов кириллицы.
Простейший вывод в виде таблицы может выглядеть так:
[<RequireQualifiedAccess>]
module PdfReport
open Model
open PdfSharp.Drawing
open SharpLayout
let private defaultSettings =
PageSettings(
TopMargin=Util.Cm(1.2),
BottomMargin=Util.Cm(1.0),
LeftMargin=Util.Cm(2.0),
RightMargin=Util.Cm(1.0))
let private createReportForTeacher teacher =
let document = Document()
let section = document.Add(Section(defaultSettings))
let font =
Font("Times New Roman", 10.0, XFontStyle.Regular, XPdfFontOptions.UnicodeDefault)
|> Option
section.Add(Paragraph().Add("Информация об преподователе", font.Value).Alignment(HorizontalAlign.Center.AsOption().ToNullable())) |> ignore
let table = section.AddTable().Font font
let c1 = table.AddColumn(Util.Px(600.0))
let c2 = table.AddColumn(Util.Px(600.0))
let r1 = table.AddRow()
let r2 = table.AddRow()
let r3 = table.AddRow()
let r4 = table.AddRow()
let r5 = table.AddRow()
r1.[c1].Add(Paragraph().Add("Имя:")) |> ignore
r1.[c2].Add(Paragraph().Add(teacher.Name)) |> ignore
r2.[c1].Add(Paragraph().Add("Фамилия:")) |> ignore
r2.[c2].Add(Paragraph().Add(teacher.LastName)) |> ignore
r3.[c1].Add(Paragraph().Add("Отчество:")) |> ignore
r3.[c2].Add(Paragraph().Add(teacher.Surname)) |> ignore
r4.[c1].Add(Paragraph().Add("Телефон:")) |> ignore
r4.[c2].Add(Paragraph().Add(teacher.Phone)) |> ignore
r5.[c1].Add(Paragraph().Add("Факультет:")) |> ignore
r5.[c2].Add(Paragraph().Add(teacher.Faculty)) |> ignore
document
Теперь что касается отображения, мне удобнее использовать WPF,
ссылка на руководство и библиотеку
Gjallarhorn.Bindable.
Для каждого типа создаем свой
UserControl который будет отвечать за ввод данных.
Каждое отображение определим в виде навигационного состояния:
[<RequireQualifiedAccess>]
type NavMessages =
| Student
| Teacher
| Enrollee
работу с каждым типом вынесем в отдельные дочерние компоненты (StudentComponent, ...). Для каждого свойства можно определить собственное правило проверки корректности.
let appComp =
Component.create<AppModel, NavMessages, Messages> [
<@ ctx.Model.Student @> |> Bind.comp (fun m -> m.Student) studentComp fst
<@ ctx.Model.Enrollee @> |> Bind.comp (fun m -> m.Enrollee) enrolleeComp fst
<@ ctx.Model.Teacher @> |> Bind.comp (fun m -> m.Teacher) teacherComp fst
<@ ctx.Model.Menu @> |> Bind.comp (fun m -> m.Menu) menuComponent fst
<@ ctx.SendReport @> |> Bind.cmd
]
Команда
SendReport будет отвечать за созданием отчета и отправку его на почту. Кнопка будет активна только в том случае, если все поля заполнены без ошибок.
Остается определить функцию обновления модели приложения:
let upd (nav : Dispatcher<NavMessages>) message model =
match message with
| Messages.SendReport ->
let v, m =
match model.Menu.Current with
| NavMessages.Enrollee ->
AccountType.Enrollee model.Enrollee, { model with Enrollee = Defaults.enrollee }
| NavMessages.Student ->
AccountType.Student model.Student, { model with Student = Defaults.student }
| NavMessages.Teacher ->
AccountType.Teacher model.Teacher, { model with Teacher = Defaults.teacher }
v
|> PdfReport.createReport
|> PdfReport.saveReport "test.pdf"
|> PdfReport.sendReport
m
| Messages.SetCurrent current ->
current |> nav.Dispatch
{ model with Menu = { model.Menu with Current = current }}
| Messages.UpdateEnrollee msg ->
{ model with Enrollee = EnrolleeComponent.update model.Enrollee msg }
| Messages.UpdateStudent msg ->
{ model with Student = StudentComponent.update model.Student msg }
| Messages.UpdateTeacher msg ->
{ model with Teacher = TeacherComponent.update model.Teacher msg }
open Gjallarhorn.Bindable.Framework
let applicationCore nav =
let navigation = Dispatcher<NavMessages>()
Framework.application init (upd navigation) appComp nav
|> Framework.withNavigation navigation
Для работы с почтой вам нужно будет указать данные с которых вы хотите отправлять письмо. Как это сделать написано
тут.
Теперь, чтобы добавить новый тип нужно будет сделать следующее:
1. Определить запись для нового объекта, описывающую его свойства.
2. Создать функцию генерирующую отчет для этого типа.
3. Создать компонент.
4. Создать пользовательский элемент управления для отображения.
5. Добавить его в общую модель программы.
В итоге получилось следующее:
Как только отчет был отправлен, запись сбрасывается до значения по умолчанию.
Для демонстрации что формы могут быть произвольными выводил сообщение с короткой информацией данные о ком заполняются в текущий момент.
В данном примере был записан такой pdf:
Весь код не приводил, так как он довольно объемный, если такой вариант интересует, то могу выложить на гитхаб.
Только учтите, что набросок можно сделать за пару часов, а довести до ума будет занимать намного больше времени.