Http://blog.csdn.net/mcai4gl2/article/details/7294625
A short project was created a while ago to generate a report. The generated report is about the stock price record. There are no ready-made packages and third-party programs for us to use. I heard that the pages rendered by WPF can be saved as PDF files. However, I did not dare to practice them. I finally used my previous methods, office InterOP, insert a lot of placeholder into a template in a Word document, then use C # code to dynamically convert placeholder into data, and then save it. This method is actually quite powerful, but there are a few restrictions and unpleasant points. First, you must install the Office on the machine where the program runs. Word is required. If you want to generate a graph, you also need excel.
Second,. Net Office InterOP is essentially a com package, so performance and stability cannot be too demanding. Third, office InterOP is still annoying. I complained for a long time, but this method is still feasible. However, what should I do if I need to generate a report in PDF format, but the Office does not support PDF generation? I think that I can directly use the pdfcreator virtual printer every time I need to generate a PDF file. I checked it and found that the pdfcreator has a COM API. This problem is solved.
In C #, how do I call the volume creator to generate a PDF file?
Step 1: Install the volume creator (this seems nonsense)
Step 2: Create a csung project and add creator.exe com to reference it
Step 3: See the following code:
[CSHARP]
View plaincopy
- Public override void process (itask task, int index)
- {
- If (! File. exists (path. Combine (fromlocation, fromfilename )))
- {
- Throw new filenotfoundexception ("file:" + path. Combine (fromlocation, fromfilename) + "does not exists ");
- }
- Monitor. Enter (lockobject );
- Clspdfcreator creator = NULL;
- Try
- {
- Creator = new clspdfcreator ();
- Creator. eerror + = new _ clspdfcreator_eerroreventhandler (creator_eerror );
- Creator. eready + = new _ clspdfcreator_ereadyeventhandler (creator_eready );
- String paramters = "/noprocessingatstartup ";
- If (! Creator. cstart ())
- {
- Throw new exception ("cannot launch failed creator. Error:" + error );
- }
- VaR opt = creator. coptions;
- Opt. useautosave = 1;
- Opt. useautosavedirectory = 1;
- Opt. autosavedirectory = This. tolocation;
- Opt. autosaveformat = 0;
- Opt. autosavefilename = This. tofilename;
- Creator. coptions = OPT;
- Creator. cclearcache ();
- Creator. cdefaprinprinter = "pdfcreator ";
- If (! Creator. cisprintable (path. Combine (fromlocation, fromfilename )))
- {
- Throw new exception ("file:" + path. Combine (fromlocation, fromfilename) + "is not printable .");
- }
- Creator. cprintfile (path. Combine (fromlocation, fromfilename ));
- Creator. cprinterstop = false;
- Ready = false;
- VaR duration = new timespan (0, 0, 0, timeoutinsec );
- Datetime lastcheck = datetime. now;
- Datetime starttime = lastcheck;
- While (! Ready & (lastcheck-starttime) <duration ))
- {
- System. Threading. thread. Sleep (500 );
- Lastcheck = datetime. now;
- }
- Creator. cprinterstop = true;
- Thread. Sleep (1000 );
- Creator. cClose ();
- If (! Ready)
- {
- Throw new exception ("PDF creation failed. This maybe due to timeout .");
- }
- }
- Finally
- {
- Monitor. Exit (lockobject );
- }
- }
- Void creator_eready ()
- {
- This. Ready = true;
- }
- Void creator_eerror ()
- {
- Error = creator. cerror. description;
- }
The code is easy to understand. I am very lazy. I didn't re-write the code into a project. I directly pasted the code in the project. If you want to use it, you need to modify it a little. The argument is that the producer Creator does not support multithreading. Therefore, if the program itself is multithreading, you need to add a lock mechanism in the Code to ensure that the calls generated by PDF are single-threaded. In addition, the default value is used for the printer name, which has not been modified. However, these problems are difficult for you to look.