Введение
Полезно создавать отчеты в формате PDF, поскольку их нельзя изменить, а также их можно легко распечатать. Здесь мы поговорим о том, как генерировать отчеты с помощью UniPDF в виде табличных данных. Мы рассмотрим это на примере создания индивидуальных табелей успеваемости для учащихся из заданного набора данных.
Сначала мы рассмотрим генерацию данных. Здесь мы будем использовать структуры и заполнять данные вручную, но мы могли бы легко предоставить входные данные в виде файла Excel XLSX и использовать UniOffice для загрузки данных. Возможно, мы добавим это в будущем. Дайте нам знать, если вы заинтересованы.
Затем мы рассмотрим, как UniPDF создает таблицу, как вставлять ячейки и форматировать таблицы, а также как вставлять соответствующие данные в ячейки. После этого мы напишем все это в PDF.
Генерация данных
Мы можем использовать структуры для хранения данных. Здесь мы определили две структуры. Одна структура для хранения оценок и предметов, а другая структура, которая содержит всю информацию для учащихся, как в нашем примере имя, отметки (которая является структурой) и поведение учащихся.
type studentReportCardMark struct { Subject string Mark int } type studentReportCard struct { Name string Marks []studentReportCardMark Punctual rune Attentive rune Orderly rune Polite rune }
Мы сделали образцы данных для четырех студентов, чтобы создать наши табели успеваемости. Например, мы покажем один здесь.
var reportCards = []studentReportCard{ { Name: "Mike", Marks: []studentReportCardMark{ { Subject: "Chemistry 101", Mark: 21, }, { Subject: "Physics 101", Mark: 13, }, { Subject: "English 101", Mark: 50, }, { Subject: "Science 101", Mark: 23, }, { Subject: "Biology 101", Mark: 26, }, { Subject: "Computers 101", Mark: 33, }, { Subject: "Tech 101", Mark: 34, }, { Subject: "BioChem 101", Mark: 14, }, }, Punctual: 'C', Attentive: 'B', Orderly: 'B', Polite: 'A', } }
Дизайн отчета
Для оформления всего табеля мы использовали таблицы из UniPDF. Для таблиц мы определили карту стилей ячеек, которая содержит данные для различных типов ячеек, которые мы хотим создать в наших таблицах для этого дизайна. Он был реализован через структуру, которая содержит свойства отдельных ячеек. Это довольно удобно и легко добавлять и изменять стили.
type cellStyle struct { ColSpan int HAlignment creator.CellHorizontalAlignment BackgroundColor creator.Color BorderSide creator.CellBorderSide BorderStyle creator.CellBorderStyle BorderWidth float64 BorderColor creator.Color Indent float64 }
Один из таких примеров стиля ячейки, используемого в этом дизайне, используется для написания заголовка слева от ячейки.
var cellStyles = map[string]cellStyle{ "heading-left": { BackgroundColor: creator.ColorRGBFromHex("#332f3f"), HAlignment: creator.CellHorizontalAlignmentLeft, BorderColor: creator.ColorWhite, BorderSide: creator.CellBorderSideAll, BorderStyle: creator.CellBorderStyleSingle, BorderWidth: 6, }
Точно так же в табеле успеваемости использовались разные стили ячеек для создания ячеек, которые описаны ниже.
Заголовок
Для заголовка мы использовали таблицу из 1 ячейки с выравниванием по центру и использовали прямоугольник, чтобы выделить фон заголовка табеля успеваемости. Похоже на это.
Код выглядит следующим образом. И он также включает в себя две линии в конце, которые были нарисованы с помощью функции newLine.
// Filled rectangle on top. rect := c.NewRectangle(0, 0, creator.PageSizeLetter[0], 120) rect.SetFillColor(creator.ColorRGBFromHex("#dde4e5")) rect.SetBorderWidth(0) c.Draw(rect) headerStyle := c.NewTextStyle() headerStyle.FontSize = 50 // Table with 1 column to center the text. table := c.NewTable(1) table.SetMargins(0, 0, 20, 0) drawCell(table, newPara(c, "Report Card", headerStyle), cellStyles["centered"]) c.Draw(table) // Double line. line := c.NewLine(0, 120, creator.PageSizeLetter[0], 120) line.SetLineWidth(5) c.Draw(line) line = c.NewLine(0, 123, creator.PageSizeLetter[0], 123) line.SetLineWidth(1.5) c.Draw(line)
Создание описания ученика
Аналогичным образом, используя таблицу из 3 столбцов, для каждого учащегося было создано описание с использованием данных, которые были добавлены в образец, и некоторых общих данных для остальных столбцов.
Это было сделано с помощью функции drawCell, которая была разработана для рисования отдельных ячеек в соответствии с нашими потребностями в данной таблице.
drawCell(table, newPara(c, "Student Name: "+card.Name, studentInfoStyle), cellStyles["left"]) drawCell(table, newPara(c, "School Year: 2020", studentInfoStyle), cellStyles["left"]) drawCell(table, newPara(c, "Roll No: 320", studentInfoStyle), cellStyles["left"]) drawCell(table, newPara(c, "Date: 14/12/2020", studentInfoStyle), cellStyles["left"]) drawCell(table, newPara(c, "Department: Bachelors of Arts", studentInfoStyle), cellStyles["left"])
Таблица оценок с индивидуальными баллами по предметам
Таблица оценок была создана с использованием выборочных данных, и некоторые функции использовались для создания оценок, а затем добавления их в таблицу для отдельных предметов. Тема выравнивается по левому краю, а остальные столбцы выравниваются по центру.
Код выглядит следующим образом
for _, mark := range card.Marks { drawCell(table, newPara(c, " "+mark.Subject, regularStyle), cellStyles["left-highlighted"]) s := mark.Mark percent := (float64(s) / 50.0) * 100.0 drawCell(table, newPara(c, fmt.Sprintf("%d", s), regularStyle), cellStyles["centered-highlighted"]) drawCell(table, newPara(c, fmt.Sprintf("%.0f%%", percent), regularStyle), cellStyles["centered-highlighted"]) drawCell(table, newPara(c, calcGrade(percent), regularStyle), cellStyles["centered-highlighted"]) }
Схема оценок и колонка поведения
Остальная часть отчета состоит из схемы оценивания и поведения, которое снова было сгенерировано с использованием таблиц и отформатировано с использованием структуры Style ячейки, которую мы определили ранее. Схема оценивания представляет собой таблицу с одним столбцом, в которой показано, как были выставлены оценки, а поведение представляет собой таблицу с двумя столбцами для определения поведения каждого учащегося. Выравнивание этих таблиц было выполнено с помощью сетки выравнивания с 12 столбцами, где таблицы оценок и поведения были помещены в столбцы столбцов 1 и 8 соответственно, создавая по 3 и 5 столбцов в каждой.
// 12-column table for alignment (grid). grid := c.NewTable(12) grid.SetMargins(0, 0, 50, 0) gradeInfoStyle := c.NewTextStyle() gradeInfoStyle.Font = font gradeInfoStyle.FontSize = 15 // Grading system table. table = c.NewTable(1) drawCell(table, newPara(c, "Grading System:", boldStyle), cellStyles["gradingsys-head"]) drawCell(table, newPara(c, "\u2022 A > 80%", gradeInfoStyle), cellStyles["gradingsys-row"]) drawCell(table, newPara(c, "\u2022 B > 70%", gradeInfoStyle), cellStyles["gradingsys-row"]) drawCell(table, newPara(c, "\u2022 C > 60%", gradeInfoStyle), cellStyles["gradingsys-row"]) drawCell(table, newPara(c, "\u2022 D > 50%", gradeInfoStyle), cellStyles["gradingsys-row"]) drawCell(table, newPara(c, "\u2022 F < 50%", gradeInfoStyle), cellStyles["gradingsys-row"]) grid.MultiColCell(3).SetContent(table) grid.SkipCells(4) // Conduct table. table = c.NewTable(2) table.SetColumnWidths(0.6, 0.4) drawCell(table, newPara(c, "Conduct:", boldStyle), cellStyles["conduct-head"]) table.SkipCells(1) drawCell(table, newPara(c, "Punctual:", gradeInfoStyle), cellStyles["conduct-key"]) drawCell(table, newPara(c, string(card.Punctual), gradeInfoStyle), cellStyles["conduct-val"]) drawCell(table, newPara(c, "Attentive:", gradeInfoStyle), cellStyles["conduct-key"]) drawCell(table, newPara(c, string(card.Attentive), gradeInfoStyle), cellStyles["conduct-val"]) drawCell(table, newPara(c, "Orderly:", gradeInfoStyle), cellStyles["conduct-key"]) drawCell(table, newPara(c, string(card.Orderly), gradeInfoStyle), cellStyles["conduct-val"]) drawCell(table, newPara(c, "Polite:", gradeInfoStyle), cellStyles["conduct-key"]) drawCell(table, newPara(c, string(card.Polite), gradeInfoStyle), cellStyles["conduct-val"]) grid.MultiColCell(5).SetContent(table) c.Draw(grid)
Создание выходного файла PDF
В конце концов, PDF-файл можно сгенерировать с помощью функции WriteToFile, которая использовалась в функции generateReports.
// Write to output file. if err := c.WriteToFile(card.Name + "_marksheet.pdf"); err != nil { log.Fatal(err) }
Вся функция
func generateReports(font, fontBold *model.PdfFont, cards []studentReportCard) error { for _, card := range cards { // Creating Reports c := creator.New() c.SetPageMargins(40, 40, 0, 0) // Filled rectangle on top. rect := c.NewRectangle(0, 0, creator.PageSizeLetter[0], 120) rect.SetFillColor(creator.ColorRGBFromHex("#dde4e5")) rect.SetBorderWidth(0) c.Draw(rect) headerStyle := c.NewTextStyle() headerStyle.FontSize = 50 // Table with 1 column to center the text. table := c.NewTable(1) table.SetMargins(0, 0, 20, 0) drawCell(table, newPara(c, "Report Card", headerStyle), cellStyles["centered"]) c.Draw(table) // Double line. line := c.NewLine(0, 120, creator.PageSizeLetter[0], 120) line.SetLineWidth(5) c.Draw(line) line = c.NewLine(0, 123, creator.PageSizeLetter[0], 123) line.SetLineWidth(1.5) c.Draw(line) // writing Marks writeMarks(c, font, fontBold, card) // Line on bottom. line = c.NewLine(0, creator.PageSizeLetter[1]-3, creator.PageSizeLetter[0], creator.PageSizeLetter[1]-3) line.SetLineWidth(5) c.Draw(line) line = c.NewLine(0, creator.PageSizeLetter[1], creator.PageSizeLetter[0], creator.PageSizeLetter[1]) line.SetLineWidth(1.5) c.Draw(line) // Write to output file. if err := c.WriteToFile(card.Name + "_marksheet.pdf"); err != nil { log.Fatal(err) } } return nil }
Заключительный отчет
Окончательный отчет после составления всех таблиц и добавления соответствующей информации выглядит следующим образом.
Представление
Наконец, мы хотим проверить производительность генерации нашего отчета.
Добавляем в начало нашего кода
func main() { start := time.Now()
и в конце основной функции
end := time.Now() fmt.Printf("diff: %v\n", end.Sub(start)) }
Это дает нам общее время для создания всех 5 отчетов для 5 студентов. Результат, который мы получаем,
diff: 36.193497ms
Итак, около 36,2 мс или 7,2 мс. Это означает, что за одну секунду мы можем генерировать сотни отчетов или в веб-системе мы можем предоставлять отчеты в формате PDF в режиме реального времени одним нажатием кнопки.
Пример игровой площадки: полный табель успеваемости учащихся
Полный код и вывод на нашу игровую площадку, где его можно редактировать и перегенерировать по желанию.
https://play.unidoc.io/p/98b800fa3f735b61
Вывод
UniPDF можно использовать для создания профессиональных отчетов с минимальными усилиями, он прост в освоении и обеспечивает превосходную производительность. Есть много вещей, которые можно сделать таким образом, например, генерировать финансовые отчеты, общедоступные данные, медицинские записи о состоянии здоровья, UniPDF может предоставить основу для создания большого количества отчетов за короткое время.