[英]Draw ShapeType.Line objects in all directions with GemBox.Document
高级业务需求:
1.)抓取用户输入,以创建用于构造线条,矩形, text
和fields
对象数据。
2.)使用用户通过GemBox.Document
创建的doc模板的input
(当前在此处停留GemBox.Document
)3.)将工作对象合并数据摄取到doc template
以填充字段,另存为图像。
我相信我应该能够找出矩形和文本的#2,因为对象的构造方式类似于Shape对GemBox.Document
工作GemBox.Document
。 但是,Line的对象不同,提供的是point1
和length / width,而不是point1
和point2
。
我正在对3种类型的线进行分类...
1.)扁平2.)正螺距3.)负螺距
...我已经能够算出平坦的(没有水平或垂直的变化量)和正的螺距(从左上角到右下角的线,或者从镜子的右下角到左上角的线),但是却无法找出负的螺距(从右上角到左下角的直线或它的镜像左下角到右上角)
Shape对象将不允许负长度或具有负值的属性,使其以我想要的方式绘制。 我看不到/想不知道是否有一种方法可以通过旋转/翻转等方式改变线对象。
我对各种方法GemBox.Document
开放态度,但有人告诉我必须使用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;
}
}
}
正如Mario Z提到的那样,新的大修正版本v1099确实允许对线条进行转换以创建我归类为负间距线的东西...现在可以在所有方向上绘制线。
似乎有些错误,因为FlipVertical和FlipHorizontal似乎在不应该进行相同的准确转换。 我还发现了一个通过RightMargin设置浮点的小错误,它的功能似乎与顶部/左侧的功能不同(我还没有尝试过使用底部)。
public static Shape GetGemboxLineShape(DocumentModel document, Section section, TemplateItem templateItem, double heightMultiplier, double widthMultiplier)
{
var size = new GemBox.Document.Size(Math.Abs(templateItem.X2 - templateItem.X) * widthMultiplier, Math.Abs(templateItem.Y2 - templateItem.Y) * heightMultiplier, LengthUnit.Point);
var horizontal = new HorizontalPosition();
var vertical = new VerticalPosition();
var requiresNegativeTransform = false;
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
{
horizontal = new HorizontalPosition(section.PageSetup.PageMargins.Left + (templateItem.X * widthMultiplier), LengthUnit.Point, HorizontalPositionAnchor.LeftMargin);
vertical = new VerticalPosition(section.PageSetup.PageMargins.Top + (templateItem.Y * heightMultiplier), LengthUnit.Point, VerticalPositionAnchor.TopMargin);
}
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
horizontal = new HorizontalPosition(section.PageSetup.PageMargins.Left + (templateItem.X2 * widthMultiplier), LengthUnit.Point, HorizontalPositionAnchor.LeftMargin);
vertical = new VerticalPosition(section.PageSetup.PageMargins.Top + (templateItem.Y2 * heightMultiplier), LengthUnit.Point, VerticalPositionAnchor.TopMargin);
}
else if (templateItem.X < templateItem.X2 && templateItem.Y > templateItem.Y2)//negative pitch, point 1 below/ToLeft point 2
{
//so for ease we're going to pick point2 at the top right and we can use Top/Right margin as our origin instead of Top/Left
//however, this appears a bit buggy, i would assume i'd need to do -section.PageSetup.PageMargins.Right minus relative (opposite of TopLeft on the X/horizontal)
//but it appears this wasn't accounted for on the right margin? or i'm not entirely understanding the floating/anchor functionality
horizontal = new HorizontalPosition(-(templateItem.X2 * widthMultiplier), LengthUnit.Point, HorizontalPositionAnchor.RightMargin);
vertical = new VerticalPosition(section.PageSetup.PageMargins.Top + (templateItem.Y2 * heightMultiplier), LengthUnit.Point, VerticalPositionAnchor.TopMargin);
requiresNegativeTransform = true;
}
else if (templateItem.X > templateItem.X2 && templateItem.Y < templateItem.Y2)//negative pitch, point 1 above/ToRight point 2
{
//opposite of previous in that we're going to pick point1 but everything else will be the same
horizontal = new HorizontalPosition(-(templateItem.X * widthMultiplier), LengthUnit.Point, HorizontalPositionAnchor.RightMargin);
vertical = new VerticalPosition(section.PageSetup.PageMargins.Top + (templateItem.Y * heightMultiplier), LengthUnit.Point, VerticalPositionAnchor.TopMargin);
requiresNegativeTransform = true;
}
else
{
throw new ArgumentException();
}
var gemboxLineShape = new Shape(document, ShapeType.Line, GemBox.Document.Layout.Floating(horizontal, vertical, size));
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;
//this appears to solve my problem.... however, similar to right margin appears to be
//a bit buggy... at least in the sense that FlipVertical and FlipHorizontal should do different transformations but it doesn't
gemboxLineShape.Layout.Transform.FlipVertical = requiresNegativeTransform;
return gemboxLineShape;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.