Synfusion File Formats: Doc

Public forum to share code snippets, screen shorts, experiences, etc.
Post Reply
Frank Maraite
Posts: 178
Joined: Sat Dec 05, 2015 10:44 am
Location: Germany

Synfusion File Formats: Doc

Post by Frank Maraite »

Hi all,

Dick gave us an advice (Dick's advice ) to use free software recently.

This was really good. Thanks Dick!.

One of the first things I tried is the file format library. They have PDF, DocIO (Word, all Versions down to Word97), Presentation and XlsIO. The good thing is: we don't need Acrobat or Office installed on our machines nor on the client machines. They fully implemented the document object models.

Here I will show how simple the creation of a word document is (partially translated to X# from File Formats User Guide):

Code: Select all


USING Syncfusion.DocIO  // Syncfusion.DocIO.Base.dll
USING Syncfusion.DocIO.DLS
USING System.Drawing   // System.Drawing (GAC)

FUNCTION Start( ) AS VOID
	System.Console.WriteLine("Hello x#!")
	
	LOCAL	Document AS WordDocument
	Document := WordDocument{}
	
// Set PageSettings
	
	LOCAL Section AS IWSection
	Section := Document:AddSection()
	
	LOCAL FirstParagraph AS IWParagraph
	FirstParagraph := Section:AddParagraph()
	
	FirstParagraph:ParagraphFormat:HorizontalAlignment := HorizontalAlignment.Justify
	
	LOCAL firstTextRange AS IWTextRange
	firstTextRange := FirstParagraph:AppendText("Lorem")
//sets the font formatting of the text range
	firstTextRange:CharacterFormat:Bold := TRUE
	firstTextRange:CharacterFormat:FontName := "Calibri"
	firstTextRange:CharacterFormat:FontSize := 14
//Adds another text range into the paragraph
	
	LOCAL secondTextRange AS IWTextRange
	secondTextRange := firstParagraph:AppendText(" ipsum dolor sit"+;
		"amet, consectetur adipiscing elit, sed DO eiusmod tempor incididunt ut"+;
		"labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud"+;
		"exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. ")
//sets the font formatting of the text range
	secondTextRange:CharacterFormat:FontName := "Courier New"
	secondTextRange:CharacterFormat:FontSize := 11
	secondTextRange:CharacterFormat:OutLine := TRUE
	
	firstParagraph := Section:AddParagraph()
	firstTextRange := FirstParagraph:AppendText("Bold 12364")
//sets the font formatting of the text range
	firstTextRange:CharacterFormat:Bold := TRUE
	firstTextRange:CharacterFormat:FontName := "Courier New"
	firstTextRange:CharacterFormat:FontSize := 11
	firstTextRange:CharacterFormat:Bold := TRUE
	
	firstParagraph := Section:AddParagraph()
	firstTextRange := FirstParagraph:AppendText("Cond 123456")
//sets the font formatting of the text range
	firstTextRange:CharacterFormat:Bold := TRUE
	firstTextRange:CharacterFormat:FontName := "Courier New"
	firstTextRange:CharacterFormat:FontSize := 11
	firstTextRange:CharacterFormat:CharacterSpacing := -2.0
	
	firstTextRange := FirstParagraph:AppendText("Blauer Text")
//sets the font formatting of the text range
	firstTextRange:CharacterFormat:Bold := TRUE
	firstTextRange:CharacterFormat:FontName := "Arial"
	firstTextRange:CharacterFormat:FontSize := 14
	firstTextRange:CharacterFormat:TextColor := Color.Blue
	
	firstTextRange := FirstParagraph:AppendText("Roter Text")
//sets the font formatting of the text range
	firstTextRange:CharacterFormat:Bold := TRUE
	firstTextRange:CharacterFormat:FontName := "Times New Roman"
	firstTextRange:CharacterFormat:FontSize := 12
	
	firstTextRange:CharacterFormat:TextColor := Color.Red
	
	Document:Save( "Result.docx" )
	document:Close()
	Document := NULL
	
RETURN
All we need is references to
System
System.Drawing
and
Syncfusion.DocIO.Base.dll

Compiled with X#/Core.

Hope this helps someone like it helped me.

Cheers
Frank
User avatar
Phil Hepburn
Posts: 743
Joined: Sun Sep 11, 2016 2:16 pm

Synfusion File Formats: Doc

Post by Phil Hepburn »

Hi Frank,

Thanks for sharing.

Can you do some of this stuff at Cologne perhaps ?

Cheers,
Phil.
Frank Maraite
Posts: 178
Joined: Sat Dec 05, 2015 10:44 am
Location: Germany

Synfusion File Formats: Doc

Post by Frank Maraite »

Hi Phil et al,

what do you expect? Working with this library or the process of registering, choosing the right package etc. to get and work with?

At the end it is advertising for Syncfusion. Is this intended?

What I did so far is mapping my simple or better to say primitive printing from clipper style to doc and pdf. It works like a charm.

Frank
User avatar
Phil Hepburn
Posts: 743
Joined: Sun Sep 11, 2016 2:16 pm

Synfusion File Formats: Doc

Post by Phil Hepburn »

Hi guys, and thanks also to Dick,

I personally have now "joined the club" and downloaded and installed the 'free to small guys' library / framework.

It took quite a quite to open my Visual Studio the first time after installing the Syncfusion tools.
syncfFree_01.jpg
syncfFree_01.jpg (83.31 KiB) Viewed 588 times
However, I have to say that I do have some reservations about using third party tools generally - I got stuck a few times when WPF was young (early days) and some important tools were missing, the free extra toolbox/toolkit classes were great until I had to maintain the apps some time later, possibly a year or two down the line. It still gives me grief today ;-0(

We have no control over what Syncfusion does in the future. What if they start charging us for the use of their tools, and we have not budgeted for it with our customers etc. ?

Reading the Forum posts (this and Vulcan before) it seems to me that most grief is caused to developers by the 'past use' of third party tools.

My approach now is to try and find a pure X# solution, and get a free library which can be maintained by myself. Then I always have got it. For example. Frank's recent document 'development' can be done from the free printing library I have had on offer to all for almost ten years. This, now X#, library can be changed and maintained by any user, and seems as easy to use as what Frank posted.

Now then, having said all that sort of negative stuff, what about Dick doing a session at any future 'DevShare' on the Syncfusion WPF tools ? There's a positive idea !

Best regards,
Phil.
Wales, UK.
User avatar
Phil Hepburn
Posts: 743
Joined: Sun Sep 11, 2016 2:16 pm

Synfusion File Formats: Doc

Post by Phil Hepburn »

Sorry !

should have said ..... it took quite a while (some time) to open VS the first time ......

Phil.
NickFriend
Posts: 248
Joined: Fri Oct 14, 2016 7:09 am

Synfusion File Formats: Doc

Post by NickFriend »

Hi Phil,

I disagree almost entirely with your sentiments about 3rd party products!! The trouble is, coming from the relatively tiny VO community we're used to the semi-amateur school of add-ons. Most of the things we were using were created by VO community members and maintained and developed as side projects.

With .Net we can now tap into a huge variety of professionally created and supported products (and of course the .Net Framework itself is the biggest 3rd party product any of us will ever use!).

My point of view is why reinvent the wheel - why spend a huge amount of costly development time eg. writing your own grid control, when you can simply buy one, slot it in, and then get on with what we should really be doing which is creating line-of-business applications.

I started using the DevExpress toolkit a few years back, and happily pay a few hundred dollars each year to stay up to date. The level of functionality of the controls is way beyond what most of us would be capable of producing on our own, especially given the huge variety of controls these companies supply, and the technical support is unreservedly superb. I'm sure Syncfusion is similar.

What I would be doing though is planning to pay for the products at some point, because I imagine this free give away is just to build up a bit of market share. Also if you've paid for something, it gives you the right to demand service from the supplier.... not so easy when it's a freebie.

My 2 cents

Nick
User avatar
Phil Hepburn
Posts: 743
Joined: Sun Sep 11, 2016 2:16 pm

Synfusion File Formats: Doc

Post by Phil Hepburn »

Okay Nick,

I suppose I agree with all what you said really :S

However, if we leave everything to others then we do lose some capabilities / skills ourselves.

Having had to print all my own documents since back in VO times, I have not been aware that then, or in my ten years of .NET, there was any suitable tool for me to design and print my own 'fancy' invoices. I have heard nothing from the various Forums, or sessions and guys at conferences. Oh! apart from Alwyn, who did everything himself, and whom I followed.

So use libraries and frameworks, but be fully prepared to pay for them.

Oh! and by the way, like everything, there are good and bad third party products, so choose wisely is my advice.

Now then, go and disagree with all that :unsure:

Cheers,
Phil.
Wales, UK.
Frank Maraite
Posts: 178
Joined: Sat Dec 05, 2015 10:44 am
Location: Germany

Synfusion File Formats: Doc

Post by Frank Maraite »

Hi Phil and Nick,

you both are saying good things. The trick is how to bind to the 3rd party tools.

The magic thing is: "Decouple the systems. Compile against interfaces, not to implementations.". Then we are less dependend on specific tools. Later this day I hope I can show you how I did it.

And yes, I would like to use Phil's document class too. Be patient.

Frank
Frank Maraite
Posts: 178
Joined: Sat Dec 05, 2015 10:44 am
Location: Germany

Synfusion File Formats: Doc

Post by Frank Maraite »

Hi all,

do you remember thirty years ago. How did we print in Clipper. As I remember right

Code: Select all

Set Printer To LPT1:
? // New line
?? "In the same line"
? // "A second line"
?? CHR(12) // New page
Later I realised that ? was translated to QOut() and ?? to QQOut().

I wanted to do enhanced printing. I replaced the question marks into functions, not QOut() but my own.

Code: Select all

? -> VM_DruFZ()
?? -> VM_DruFZZ()
To explain the naming:
"VM_" was my function name prefix
Print in german is Druck
Questionmark is FrageZeichen, so double question mark double "Z"

Inside these function I did some additional work but at least they called QOUT() respective QQOut().

Code: Select all

FUNCTION VM_DruFZ()
	QOUT()
RETURN

FUNCTION VM_DruFZZ( Text AS STRING )
	QQOut( Text )
RETURN

FUNCTION VM_DruFF()
	QQOut( Chr(12) )
RETURN

VM_DruFZ() //  "New line"
VM_DruFZZ( "In the same line" )
VM_DruFZ() // "A second line"
VM_DruFF() // "New Page
In the early nineties, with Clipper 5.3, I got ClProfiW from Dr. Huggle. I integrated this lib and was then able to print on any windows printer. It works until now :-).

Code: Select all

FUNCTION VM_DruFZ()
	PrNewLine()
RETURN

FUNCTION VM_DruFZZ( Text AS STRING )
	PrWriteStr( Text )
RETURN

FUNCTION VM_DruFF()
	PrNewPage()
RETURN
and of course a little bit more to set different fonts, colors and so on.

Saying that I didn't call directly to the printer but only my own functions. So I did decoupling two decades ago.

Now I create an interface:

Code: Select all

INTERFACE IGCRPrinter
	METHOD VM_DruFZ() AS VOID
	METHOD VM_DruFZZ( Text AS STRING ) AS VOID
	METHOD VM_DruFF( ) AS VOID
END INTERFACE
Then create an abstract class for that interface:

Code: Select all

PARTIAL ABSTRACT CLASS GCRPrinterAbstract IMPLEMENTS IGCRPrinter

	METHOD IGCRPrinter.VM_DruFZ( ) AS VOID
		PrNewLine( )
	ABSTRACT METHOD PrNewLine() AS LOGIC

	METHOD IGCRPrinter.VM_DruFZZ( Text AS STRING ) AS VOID
		PrWriteStr( Text )
	ABSTRACT METHOD PrWritestr( Text AS STRING ) AS INT

	METHOD IGCRPrinter.VM_DruFF( ) AS VOID
		PrNewPage()
	ABSTRACT METHOD PrNewPage() AS LOGIC

END CLASS

This class defines methods that implement this interface, the IGCRPrinter. ones.
They call other methods, the Pr... ones. These methods have to be implemented in inherited classes. So we do

Code: Select all

PARTIAL SEALED CLASS GCRPrinterToPDF INHERIT GCRPrinterAbstract

	PRIVATE Document AS PdfDocument
	PRIVATE Page AS PdfPage
	PRIVATE Graphics AS PdfGraphics

	METHOD PrNewLine() AS LOGIC
		TextPosHorizontal := 0.0
		TextPosVertikal   += TextLineHeight
	RETURN TRUE

	METHOD PrWritestr( sOutBuff AS STRING ) AS INT

		TextElement := PdfTextElement{sOutBuff, Font }
		TextElement:Brush := Brush
      TextElement:StringFormat := StringFormat
		result := TextElement:Draw(page, PointF{TextPosHorizontal, TextPosVertikal})

		TextPosHorizontal += result:Bounds:Width
		TextLineHeight := result:Bounds:Height

	RETURN sOutBuff:Length

	METHOD PrNewPage() AS LOGIC
		Page := document:Pages:Add()
      Graphics := Page:Graphics
		TextPosHorizontal := 0.0
		TextPosVertikal   := 0.0
		TextLineHeight   := 10.0
	RETURN TRUE

END CLASS
for PDF and

Code: Select all

PARTIAL SEALED CLASS GCRPrinterToWordDoc INHERIT GCRPrinterAbstract

	PRIVATE Document AS WordDocument
	PRIVATE Section AS IWSection
	PRIVATE FirstParagraph AS IWParagraph
	PRIVATE CharacterFormat AS Syncfusion.DocIO.DLS.WCharacterFormat

	METHOD PrNewLine() AS LOGIC
		firstParagraph := Section:AddParagraph()
	RETURN TRUE

	METHOD PrWritestr( sOutBuff AS STRING ) AS INT
		TextRange := firstParagraph:AppendText( sOutBuff )
	RETURN sOutBuff:Length

	METHOD PrNewPage() AS LOGIC
		Section := Document:AddSection()
		FirstParagraph := Section:AddParagraph()
	RETURN TRUE

END CLASS
for the Word docs.

Now we have two classes following the old interface.

Go on to the business objects. In the base class the printer is set private, hiding all the printing stuff to the inherited classes. To use the printer we map the the function calls to the printer object.

Code: Select all

CLASS BusinessBase
	PRIVATE Printer AS IGCRPrinter

	METHOD SetPrinter( printer AS IGCRPrinter ) AS VOID
 		Self:Printer := Printer
 	RETURN
 	
// Mapping print functions to printer
	METHOD VM_DruFZ() AS VOID
		Printer:DruFZ()

	METHOD VM_DruFZZ( Text AS STRING ) AS VOID
		Printer:DruFZZ( Text )

	METHOD VM_DruFF( ) AS VOID
		Printer:DruFF()

END CLASS
In the working class I can now use my old interface like I ever did:

Code: Select all

CLASS Working INHERIT BusinessBase

	VM_DruFZ() //  "New line"
	VM_DruFZZ( "In the same line" )
	VM_DruFZ() // "A second line"
	VM_DruFF() // "New Page

END CLASS
Now I can adopt another printing engine with a few handful lines of code. I can leave a few tenthousend lines of code where I print untouched.
Would like to show this with Phil's printing stuff too.

But in fact I do not have only printing: I produce pdf directly or editable documents like docx. That's more then only printing.

Cheers
Frank
User avatar
Phil Hepburn
Posts: 743
Joined: Sun Sep 11, 2016 2:16 pm

Synfusion File Formats: Doc

Post by Phil Hepburn »

Hi Frank,

Yes, what you have done is interesting. You will definitely enjoy my 'Cologne 2018' session on 'Printing and Reporting' if you can manage to attend. I feel we all need to know the basics behind .NET printing, even if we use third party tools.

The class I use for all my printing is a sub-classed one I call 'BESTdocument'. It inherits from the .NET class called 'PrintDocument' - in namespace 'System.Drawing.Printing'. Now it is in X# code and I can edit it and upgrade it when I wish, adding further functionality when it is needed.

I have written a whole bunch methods which work 'on top' of the Framework class, which makes placing items to be printed on the 'graphics' surface easy for the developer. Basically, I have made methods to work with .NET as opposed to doing anything 'my way', and many such methods place an item / a graphics element, some place on the graphics surface.

In .NET the graphics printing surface can be written to in any order, and even elements placed one over the top of another. There is no concept of a page - only the shape of landscape and portrait which comes from the printer driver of the selected printer. We have to do the page metaphor stuff ourselves.

So my method 'tools' now allow me to place a paragraph of text anywhere on the surface, and have this justified if required (left, right, fully, none ...) as well as it being displayed between two 'across' ('X') values. It is quite complex, since as you say we can specify text colour, size, and font and style.

Attached is a simple example of a standard letter we used to do for my customer in Cardiff.
FrankPrint_01.jpg
FrankPrint_01.jpg (88.38 KiB) Viewed 588 times
Obviously, one of my methods allows a double lined box to be placed on the surface to be printed.

You may be interested to know that some of the document detail is a standard template type stuff, and other is from a database. So in some way it could be classed as a report I suppose.

Hope this interests you and a few more guys ;-0)

Notice the 'Print Preview' window, this is a great benefit in .NET to what we could do in VO.

Cheers,
Phil.
Wales, UK.
Post Reply