Using XML to implement universal web report printing (3)

xiaoxiao2021-03-06  106

.NET Web control scheme implementation and expansion

Software principle:

The principle of this software is actually very simple, that is, it is to facilitate parsing the defined XML format tag, interpret the parameter definition of the tag in the file, and finally restore this information to the printer output graphic format.

In order to express complex report styles, we need to define some tags, attach specific style information in these tags, and act similar to HTML tags, and our resolution program is equivalent to IE browser, the difference is IE The graph is output to the screen, and we are output to the printer, because the printer relative to the specialty of the display (such as paging), we cannot print directly with the web browser's label parsing function, need to be a need to meet the needs "Print Browser".

For most reports, I only define two format tags: Text and Table, their specific attribute definitions, and other settings of label definition, please refer to the forebelt, here again Figure helps readers understand. As follows:

Structural design:

To describe all style markers, I first define a abstract base class Printelement, which has a virtual method DRAW, then corresponds to the table and text, derived two subclasses from Printelement, which is Table and Text, I also created a Parser The class is used to parse different styles tags and create a corresponding object, which has a static method CreateElement that creates a corresponding object based on different format tags. The structure is shown below:

The readers who have read "design patterns" must have already seen, which applies a very famous model in design mode: Abstract Factory. The advantage of using this mode is that the label objects and parsers are independent, reducing the system coupling degree, which is advantageous to increase other format labels in the future (hereinafter will give an instance) and convenient Replace different user interfaces (the client represents a Windows application or a web plugin).

Code:

First, create a new project of "Windows Control Library", write Remoteprint at the project name, as shown below:

Then put the default UserControl1 class in the new project, and its constructor name and file name are changed to PrintControl. Set it back to white, add three press, and set their enable properties to false, the Anchor property is set to Bottom, Right, add a Label control to display program status, its Anchor property Set to Left. As shown below:

Then drag in three print objects from the control bar: PrintDocument, PagesetupDialog, PrintPreviewDialog, as shown below:

All Document properties of PageSetupDialog1 and PrintPreviewDialog1 are set to PrintDocument1.

Then add a new class of Printelement to the project, the code is as follows:

Using system; using system.drawing; namespace remotEprint {public copublic class printelement {public printelement () {} public virtual bool Draw (graphics g) {Return False;}}}

There is only one virtual method DRAW in this class, pay attention to it specifies that a BOOL value needs to be returned. This value is used to indicate whether the label is printed in the page. Then add a Table new class, the code is as follows:

using System; using System.Xml; using System.Drawing; namespace RemotePrint {public class Table: PrintElement {private XmlNode table; public static int count = 0, pc = 1; public Table (XmlNode Table) {table = Table;} public Override Bool Draw (File: // Table Coordinate INT TABLEX = INT.PARS (Table.Attributes ["X"]. InnerText); int Tabley = Int.Parse (Table.attributes ["Y"]. InnerText ); int x = Tablex, y = Tabley; DrawTopline (g, table); // Painting Table Pen Pen = new pen (color.attributes ["bordercolor"]. innerText), float.parse Table.attributes ["Border"]. InnerText); int trueight = 0; file: // Header Foreach (XMLNode Tr in Table ["TableHead"]. ChildNodes) {Trhem = Int.Parse (Tr.attributes [" Height "]. innerText); DrawTR (x, y, tr, pen, g); y = trheight;} file: // entry for (INT i = 0; i

Bordercolor "]. innerText), float.parse (Table.attributes [" Border "]. InnerText); int width = 0; Foreach (XMLNode Td in table.firstchild.FirstChild) {width = int.Parse (TD. Attributes ["width"]. InnerText);} int x = int.parse (Table.Attributes ["x"]. InnerText); int y = int.parse (Table.Attributes ["y"]. InnerText); g .Drawline (Pen, X, Y, X Width, Y);} File: // Picture of Private Void Drawtr (INT X, INT Y, XMLNode Tr, Pen Pen, Graphics G) {INT Height = Int.Parse (Tr.attributes ["Height"]. InnerText); int width; g.drawline (Pen, X, Y, X, Y height); // Draw left end Foreach (XMLNode TD IN TD) {width = int. PARSE (TD.Attributes ["Width"]. InnerText); DrawTD (X, Y, Width, Height, TD, G); G. Drawline (Pen, X Width, Y, X Width, Y Height); // Right Line G. Drawline (Pen, X, Y Height, X Width, Y Height); // Bottom Line X = Width;}} File: // Sex PRIVATE VOID DRAWTD (int x, int Y, int Width, INT Height, XMLNode TD, Graphics G) {Brush Brush = New Solidbrush (Color.FromName (Td.attributes ["BGColor"]. Innertext); G.FillRectangle (Brush, x, y, width, Height); FontStyle Style = FontStyle.Regular; file: // Set font pattern IF (td.attributes ["b"]. InnerText == "true") style | = fontstyle.bold; if (td.attributes ["i"]. InnerText = = "true") style | = fontStyle.italic; if (td.attributes ["u"]. InnerText == "true") style | = fontstyle.underline; font font = new font (tdname " ] .InnerText, float.Parse (td.Attributes [ "fontsize"] InnerText.), style); brush = new SolidBrush (Color.FromName (td.Attributes [ "fontcolor"] InnerText.)); StringFormat sf = new StringFormat ();

File: // Set alignment Switch (Td.attributes ["align"]. innerText) {copy "center": sf.cent.Alignment = stringalignment.center; Break; Case "Right": sf.Alignment = stringalignment.near; Break Default: sf.alignment = stringalignment.far; break;} sf.LineAlignment = stringalignment.center; Rectanglef Rect = New Rectanglef (FLOAT) X, (Float) Y, (float) width, (float); g .Drawstring (TD.INNERTEXT, FONT, BRUSH, RECT, SF);}}} The Table class will be independent, all of which are independently inside the table tag, all of which are completed inside the class, so that we are parsing the top layer tag as long as It is directly handed over to the Table class directly to the Table class. Don't care about it.

Add another Text class, the code is as follows:

using System; using System.Xml; using System.Drawing; namespace RemotePrint {public class Text: PrintElement {private XmlNode text = null; public Text (XmlNode Text) {text = Text;} public override bool Draw (Graphics g) {Font font = new font (text.Attributes [ "fontname"] InnerText, int.Parse (text.Attributes [ "fontsize"] InnerText)..); Brush brush = new SolidBrush (Color.FromName (text.Attributes [ "fontcolor" ] .Innertext); g.drawstring (Text.innertext, font, brush, float.parse (text.attributes ["x"]. InnerText), float.parse (text.attributes ["y"]. InnerText)) Return false;}}}

Like the Table class, the Text class completes parsing and printing of the Text tag, but because of the simplicity of Text, it has a lot less code. Both them inherit from Printelement, which is heavy as the implementation of the DRAW method.

转载请注明原文地址:https://www.9cbs.com/read-122902.html

New Post(0)