Высокоуровневая бизнес-потребность:
1.) Получение ввода от пользователя для создания данных объекта для построения линий, прямоугольников, text
и fields
.
2.)Используя input
от пользователя, создайте шаблоны документов с помощью GemBox.Document
(в настоящее время здесь застряли строки). 3.) Входной рабочий объект объединяет данные в документы template
(s) для заполнения полей, сохраняя их как изображение.
Я считаю, что я должен быть в состоянии выяснить # 2 для прямоугольников и текста, так как способ построения объектов похож на то, как Shape работает для GemBox.Document
.Тем не менее, объект для Line не тот же, обеспечивая point1
и длину / ширину, а не point1
и point2
.
Я классифицирую 3 типа линий ...
1.) Плоский 2.) Положительный шаг 3.) Отрицательный шаг
... Мне удалось выяснить плоскую (без горизонтальной или вертикальной дельты) и положительную высоту (линия сверху слева досправа внизу или его зеркала снизу справа вверху слева), но не удалось определить отрицательный шаг (линия сверху вниз справа налево или его зеркало снизу слева направо вверх).
Объект Shape не будетпозвольте отрицательной длине или отрицательному атрибуту нарисовать его так, как я хочу.Я не мог видеть / выяснить, был ли способ изменить объект линии с помощью поворота / отражения и т. Д.
Я открыт для разных подходов, но мне сказали, что я должен использовать GemBox.Document
namespace GemBoxDocument_LineDemo
{
using System;
using MyModels;
using GemBox.Document;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GemBox.Document.Drawing;
using System.IO;
using System.Reflection;
public class Program
{
//inputs come from a GUI window, we're working with stub/coupon/partial-page/rectangle where w > h
private const float GUIWIDTH = 425;
private const float GUIHEIGHT = 200;
public static void Main(string[] args)
{
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
var gemDoc = new DocumentModel();
var firstSection = new Section(gemDoc);
gemDoc.Sections.Add(firstSection);
var firstParagraph = new Paragraph(gemDoc);
firstSection.Blocks.Add(firstParagraph);
var workableWidth = firstSection.PageSetup.PageWidth - (firstSection.PageSetup.PageMargins.Left + firstSection.PageSetup.PageMargins.Right);
//i think this needs to be -something, or * % of total page since we're partial page
var workableHeight = firstSection.PageSetup.PageHeight - (firstSection.PageSetup.PageMargins.Top + firstSection.PageSetup.PageMargins.Bottom);
var widthMultiplier = workableWidth / GUIWIDTH;
//for now this has been working just fine...
var heightMultiplier = widthMultiplier;
//offset of 0 is whole available workable width from GUI, simulating the offset at 50 for instance will show dynamic input shrinks towards center as this increases
//don't change it too high as it'd create dynamic negative input which isn't possible fron an input perspective. (negative width and/or height)
var offset = 0;
var flatOnHorizontalTOPLine = new TemplateItem()
{
X = 0 + offset,
Y = 0 + offset,
X2 = GUIWIDTH - offset,
Y2 = 0 + offset,
Pen = new System.Drawing.Pen(System.Drawing.Color.Black, 1),
TemplateItemType = TemplateItemType.Line
};
var flatOnHorizontalBOTTOMLine = new TemplateItem()
{
X = 0 + offset,
Y = GUIHEIGHT - offset,
X2 = GUIWIDTH - offset,
Y2 = GUIHEIGHT - offset,
Pen = new System.Drawing.Pen(System.Drawing.Color.Black, 1),
TemplateItemType = TemplateItemType.Line
};
var flatOnVerticalLEFTLine = new TemplateItem()
{
X = 0 + offset,
Y = 0 + offset,
X2 = 0 + offset,
Y2 = GUIHEIGHT - offset,
Pen = new System.Drawing.Pen(System.Drawing.Color.Black, 1),
TemplateItemType = TemplateItemType.Line
};
var flatOnVerticalRIGHTLine = new TemplateItem()
{
X = GUIWIDTH - offset,
Y = 0 + offset,
X2 = GUIWIDTH - offset,
Y2 = GUIHEIGHT - offset,
Pen = new System.Drawing.Pen(System.Drawing.Color.Black, 1),
TemplateItemType = TemplateItemType.Line
};
var positivePitchPoint1LessThanPoint2 = new TemplateItem()
{
X = 0 + offset,
Y = 0 + offset,
X2 = GUIWIDTH - offset,
Y2 = GUIHEIGHT - offset,
Pen = new System.Drawing.Pen(System.Drawing.Color.Black, 1),
TemplateItemType = TemplateItemType.Line
};
var positivePitchPoint1GreaterThanPoint2 = new TemplateItem()
{
X = 0 + offset,
Y = 0 + offset,
X2 = GUIWIDTH - offset,
Y2 = GUIHEIGHT - offset,
Pen = new System.Drawing.Pen(System.Drawing.Color.Blue, 1),
TemplateItemType = TemplateItemType.Line
};
//else if (templateItem.X < templateItem.X2 && templateItem.Y > templateItem.Y2)//negative pitch, point 1 below/ToLeft point 2
var negativePitchPoint1BelowAndToLeftOfPoint2 = new TemplateItem()
{
X = 0 + offset,
Y = GUIHEIGHT - offset,
X2 = GUIWIDTH - offset,
Y2 = 0 + offset,
Pen = new System.Drawing.Pen(System.Drawing.Color.Red, 1),
TemplateItemType = TemplateItemType.Line
};
//else if (templateItem.X > templateItem.X2 && templateItem.Y < templateItem.Y2)//negative pitch, point 1 above/ToRight point 2
var negativePitchPoint1AboveAndToRightOfPoint2 = new TemplateItem()
{
X = GUIWIDTH - offset,
Y = 0 + offset,
X2 = 0 + offset,
Y2 = GUIHEIGHT - offset,
Pen = new System.Drawing.Pen(System.Drawing.Color.Green, 1),
TemplateItemType = TemplateItemType.Line
};
firstParagraph.Inlines.Add(GetGemboxLineShape(gemDoc, firstSection, flatOnHorizontalTOPLine, heightMultiplier, widthMultiplier));
firstParagraph.Inlines.Add(GetGemboxLineShape(gemDoc, firstSection, flatOnHorizontalBOTTOMLine, heightMultiplier, widthMultiplier));
firstParagraph.Inlines.Add(GetGemboxLineShape(gemDoc, firstSection, flatOnVerticalLEFTLine, heightMultiplier, widthMultiplier));
firstParagraph.Inlines.Add(GetGemboxLineShape(gemDoc, firstSection, flatOnVerticalRIGHTLine, heightMultiplier, widthMultiplier));
firstParagraph.Inlines.Add(GetGemboxLineShape(gemDoc, firstSection, positivePitchPoint1LessThanPoint2, heightMultiplier, widthMultiplier));
firstParagraph.Inlines.Add(GetGemboxLineShape(gemDoc, firstSection, positivePitchPoint1GreaterThanPoint2, heightMultiplier, widthMultiplier));
//cannot figure out these two 'negative pitch' instances...
firstParagraph.Inlines.Add(GetGemboxLineShape(gemDoc, firstSection, negativePitchPoint1BelowAndToLeftOfPoint2, heightMultiplier, widthMultiplier));
firstParagraph.Inlines.Add(GetGemboxLineShape(gemDoc, firstSection, negativePitchPoint1AboveAndToRightOfPoint2, heightMultiplier, widthMultiplier));
gemDoc.Save(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), $"{Assembly.GetExecutingAssembly().GetName().Name}-{DateTime.Now.ToString("yyyy-MM-dd hhmmss")}.docx"));
Console.WriteLine("DONE");
Console.ReadKey();
}
public static Shape GetGemboxLineShape(DocumentModel document, Section section, TemplateItem templateItem, double heightMultiplier, double widthMultiplier)
{
var verticalTranslation = Math.Abs(templateItem.Y2 - templateItem.Y) * heightMultiplier;
var horizontalTranslation = Math.Abs(templateItem.X2 - templateItem.X) * widthMultiplier;
var horizontalAbsolutePosition = 0.0;
var verticalAbsolutePosition = 0.0;
if ((templateItem.X < templateItem.X2 && templateItem.Y < templateItem.Y2) ||//positive pitch, point1 < point2
(templateItem.X == templateItem.X2) || (templateItem.Y == templateItem.Y2))//flat on the horizontal or vertical
{
horizontalAbsolutePosition = templateItem.X * widthMultiplier;
verticalAbsolutePosition = templateItem.Y * heightMultiplier;
var gemboxLineShape = new Shape(document, ShapeType.Line, GemBox.Document.Layout.Floating(new HorizontalPosition(section.PageSetup.PageMargins.Left + horizontalAbsolutePosition, LengthUnit.Point, HorizontalPositionAnchor.LeftMargin),
new VerticalPosition(section.PageSetup.PageMargins.Top + verticalAbsolutePosition, LengthUnit.Point, VerticalPositionAnchor.TopMargin),
new GemBox.Document.Size(horizontalTranslation, verticalTranslation, LengthUnit.Point)));
gemboxLineShape.Outline.Fill.SetSolid(new GemBox.Document.Color(templateItem.Pen.Color.R, templateItem.Pen.Color.G, templateItem.Pen.Color.B));
gemboxLineShape.Outline.Width = templateItem.Pen.Width;
return gemboxLineShape;
}
else if (templateItem.X > templateItem.X2 && templateItem.Y > templateItem.Y2)//positive pitch, point1 > point2
{
//quickly found out i cannot give a negative width or height to GemBox.Document.Size
//to account for the mirror of the above condition, AKA drawing the same object but in mirror
//we just flip-flop the starting point / absolute position and create the shape the same way
horizontalAbsolutePosition = templateItem.X2 * widthMultiplier;
verticalAbsolutePosition = templateItem.Y2 * heightMultiplier;
var gemboxLineShape = new Shape(document, ShapeType.Line, GemBox.Document.Layout.Floating(new HorizontalPosition(section.PageSetup.PageMargins.Left + horizontalAbsolutePosition, LengthUnit.Point, HorizontalPositionAnchor.LeftMargin),
new VerticalPosition(section.PageSetup.PageMargins.Top + verticalAbsolutePosition, LengthUnit.Point, VerticalPositionAnchor.TopMargin),
new GemBox.Document.Size(horizontalTranslation, verticalTranslation, LengthUnit.Point)));
gemboxLineShape.Outline.Fill.SetSolid(new GemBox.Document.Color(templateItem.Pen.Color.R, templateItem.Pen.Color.G, templateItem.Pen.Color.B));
gemboxLineShape.Outline.Width = templateItem.Pen.Width;
return gemboxLineShape;
}
else if (templateItem.X < templateItem.X2 && templateItem.Y > templateItem.Y2)//negative pitch, point 1 below/ToLeft point 2
{
horizontalAbsolutePosition = templateItem.X * widthMultiplier;
verticalAbsolutePosition = templateItem.Y * heightMultiplier;
//cannot set negative height for size for it to draw up
var badLineShape = new Shape(document, ShapeType.Line, GemBox.Document.Layout.Floating(new HorizontalPosition(section.PageSetup.PageMargins.Left + horizontalAbsolutePosition, LengthUnit.Point, HorizontalPositionAnchor.LeftMargin),
new VerticalPosition(section.PageSetup.PageMargins.Top + verticalAbsolutePosition, LengthUnit.Point, VerticalPositionAnchor.TopMargin),
new GemBox.Document.Size(horizontalTranslation, verticalTranslation, LengthUnit.Point)));
badLineShape.Outline.Fill.SetSolid(new GemBox.Document.Color(templateItem.Pen.Color.R, templateItem.Pen.Color.G, templateItem.Pen.Color.B));
badLineShape.Outline.Width = templateItem.Pen.Width;
return badLineShape;
}
else if (templateItem.X > templateItem.X2 && templateItem.Y < templateItem.Y2)//negative pitch, point 1 above/ToRight point 2
{
horizontalAbsolutePosition = templateItem.X * widthMultiplier;
verticalAbsolutePosition = templateItem.Y * heightMultiplier;
//cannot set negative width for size for it to draw left
var badLineShape = new Shape(document, ShapeType.Line, GemBox.Document.Layout.Floating(new HorizontalPosition(section.PageSetup.PageMargins.Left + horizontalAbsolutePosition, LengthUnit.Point, HorizontalPositionAnchor.LeftMargin),
new VerticalPosition(section.PageSetup.PageMargins.Top + verticalAbsolutePosition, LengthUnit.Point, VerticalPositionAnchor.TopMargin),
new GemBox.Document.Size(horizontalTranslation, verticalTranslation, LengthUnit.Point)));
badLineShape.Outline.Fill.SetSolid(new GemBox.Document.Color(templateItem.Pen.Color.R, templateItem.Pen.Color.G, templateItem.Pen.Color.B));
badLineShape.Outline.Width = templateItem.Pen.Width;
return badLineShape;
}
else
return null;
}
}
}
namespace MyModels
{
using System.Drawing;
public enum TemplateItemType { Default, Box, Line, Text, Field }
public class TemplateItem
{
public TemplateItemType TemplateItemType { get; set; }
public Font Font { get; set; }
public Pen Pen { get; set; }
public float X { get; set; }
public float Y { get; set; }
public float X2 { get; set; }
public float Y2 { get; set; }
public float Width { get; set; }
public float Height { get; set; }
public string Text { get; set; }
public override string ToString()
{
switch (this.TemplateItemType)
{
case TemplateItemType.Box:
return $"<{this.TemplateItemType.ToString("G")}Item> X<{this.X}> Y<{this.Y}> W<{this.Width}> H<{this.Height}>";
case TemplateItemType.Line:
return $"<{this.TemplateItemType.ToString("G")}Item> X1<{this.X}> Y1<{this.Y}> X2<{this.X2}> Y2<{this.Y2}>";
case TemplateItemType.Text:
case TemplateItemType.Field:
return $"<{this.TemplateItemType.ToString("G")}Item> X<{this.X}> Y<{this.Y}> W<{this.Width}> H<{this.Height}> T<{this.Text}>";
}
return string.Empty;
}
}
}