C# 調用 origin 批量作圖


C# 調用 origin 批量作圖

質譜數據處理軟件中,需要批量粘貼 Origin的矢量圖到Word和PPT中,由於出圖量大,需要用代碼生成。

代碼參考了Origin 9.2中自帶的Automation Server示例代碼。

 

 

本文涉及兩部分內容,如何通過C#調用Origin.dll 和 interop.word對word 的讀寫操作。

 

目標:

文件是一個.opj文件,內容如下。我們通過C#調用相關接口來修改數據和標簽。

 

 並且輸出矢量圖 自動粘貼到word里。

 

 注意:

http://originlab.com/Orglab/dl.aspx

這個是origin官方的com組件dll文件。這個官網的文件版本是1.0.0版本,沒法用。要用origin 9 以上安裝目錄中自帶的8.0.0.0版本 origin.dll。

這個是origin官方的com組件dll文件。這個官網的文件版本是1.0.0版本,沒法用。要用origin 9 以上安裝目錄中自帶的8.0.0.0版本 origin.dll。

這個是origin官方的com組件dll文件。這個官網的文件版本是1.0.0版本,沒法用。要用origin 9 以上安裝目錄中自帶的8.0.0.0版本 origin.dll。

orgin的外部程序調用Origin指南在這里:

 http://www.originlab.com/doc/COM/

http://www.originlab.com/doc/LabTalk

思路:

C#調用Origin 類庫 將opj文件加載,獲取對象后

origin 有Labtalk函數和X-Function函數兩大系列的外部調用,

我們利用C#調用這些命令實現內容的修改。

      private Origin.IOApplication App;
      private Origin.Worksheet m_targetWks;
      private Origin.GraphLayer gl;

 

//單擊一個按鈕 創建或關閉origin實例。

   private void button9_Click(object sender, EventArgs e)
        {
            if (CheckMesg3())
            {
                if (!IsConnectedToOrigin())
                {
                    if (ConnectToOrigin())
                    {
                        if (!PrepareOrigin())
                        {
                            DisconnectFromOrigin();
                        }
                    }
                }
            }
        }

 

 

   //origin 單擊事件中用到的准備函數實現如下
  //這系列函數的原版在origin的automation Server文件夾中。
private bool IsConnectedToOrigin() { return App != null; } private bool ConnectToOrigin() { DisconnectFromOrigin(); try { // if (existingInstanceCheckBox.Checked) // App = new Origin.ApplicationSI(); // SI for existing instance // else App = new Origin.Application(); // non-SI for new instance } catch (Exception e) { string strMsg = "Failed to connect to Origin.\n" + e.Message; // ShowMessage(strMsg); } return App != null; } private void DisconnectFromOrigin() { if (IsConnectedToOrigin()) { System.Runtime.InteropServices.Marshal.FinalReleaseComObject(App); App = null; } } private bool PrepareOrigin() { string strFilePath = textBox.Text; App.Visible = Origin.MAINWND_VISIBLE.MAINWND_SHOW; // ---------- Open user specified project // GetOriginProjectFileName(ref str1);//原來是ref 進去處理了又返回引用類型 if (!App.Load(strFilePath, false)) { // ShowMessage("Failed to load Origin project\r\n" + str1); return false; } // ---------- Attach to target worksheet m_targetWks = GetOriginWorksheet("Book1", "Sheet1", true); // true = create if not found if (null == m_targetWks) { return false; } // ---------- Clear target worksheet m_targetWks.ClearData(0, -1); // ---------- Make sure target worksheet has 3 columns if (m_targetWks.Cols < 5) { m_targetWks.Columns.Add(); } // ---------- Set column long names and units // m_targetWks.Columns[0].LongName = "Time"; // m_targetWks.Columns[0].Units = "h"; // m_targetWks.Columns[1].LongName = "N29rate"; // m_targetWks.Columns[1].Units = "rate"; // m_targetWks.Columns[2].LongName = "N30rate"; // m_targetWks.Columns[2].Units = "rate."; // m_targetWks.Columns[3].LongName = "N30rateFit"; // m_targetWks.Columns[3].Units = "rate."; // ---------- Add data columns to Graph1 Origin.GraphPage gp = App.GraphPages["Graph1"]; if (null != gp) { gl = (Origin.GraphLayer)gp.Layers[0]; //先建立一個Graph1 將第一頁設為gL if (null != gl) {
          //原版函數在此新建了塗層
// Origin.DataRange dr = m_targetWks.NewDataRange(0, 0, 0, 2); // gl.DataPlots.Add(dr, Origin.PLOTTYPES.IDM_PLOT_SCATTER); // gl.Execute("layer.x.to = 8;"); // gl.Execute("layer.y.from = 0.25; layer.y.to = 10.25;"); // Setup the Y axis to auto adjust the scale to fit any data // points that are less than or greater than the scale's range. // gl.Execute("layer.disp = layer.disp | hex(1000);"); } else { return true; // ShowMessage("Failed to get graph layer."); } } else // ShowMessage("Failed to get graph page named \"Graph1\"."); { return true; } return true; }
        private Origin.WorksheetPage GetOriginWorksheetPage(string strPageName, bool bCreateIfNotFound)
        {
            Origin.WorksheetPage wksPg = App.WorksheetPages[strPageName];
            if (null == wksPg && bCreateIfNotFound)
            {
                strPageName = App.CreatePage((int)Origin.PAGETYPES.OPT_WORKSHEET, strPageName, "W", 2);
                wksPg = App.WorksheetPages[strPageName];
            }
            return wksPg;
        }

        private Origin.Worksheet GetOriginWorksheet(string strPageName, string strSheetName, bool bCreateIfNotFound)
        {
            Origin.WorksheetPage wksPg = GetOriginWorksheetPage(strPageName, bCreateIfNotFound);
            if (null == wksPg)
                return null;

            Origin.Worksheet wks = (Origin.Worksheet)wksPg.Layers[strSheetName];
            if (null == wks && bCreateIfNotFound)
            {
                wks = (Origin.Worksheet)wksPg.Layers.Add(strSheetName, 0, null, 0, null);
                wks.Activate();
            }

            return wks;
        }

 

private void button15_Click(object sender, EventArgs e)
        {


            if (CheckMesg3())
            {//checkmesg3判斷是否選中了輸出目錄
                string Str_timeCurrent = DateTime.Now.ToString("yyyy年MM月dd日HHmmss") + "批量擬合opj";
                string Str_path = textBox2.Text.Substring(textBox2.Text.LastIndexOf("\\") + 1, textBox2.Text.LastIndexOf(".") - textBox2.Text.LastIndexOf("\\") - 1);

                if (!Directory.Exists(textBox2.Text.Substring(0, textBox2.Text.LastIndexOf(".")) + Str_timeCurrent + "\\"))
                {
                    Directory.CreateDirectory(textBox2.Text.Substring(0, textBox2.Text.LastIndexOf(".")) + Str_timeCurrent + "\\");
                }
                //文件路徑
                string str_Content;//文件內容
                MSWord.Application app_Word;//Word應用程序變量
                MSWord.Document document_Word;//Word文檔變量
                                              //  object path = textBox2.Text.Substring(0, textBox2.Text.LastIndexOf(".")) + time333 + "\\" + time333 + ".docx";//保存為Word2003文檔
                object path = textBox2.Text.Substring(0, textBox2.Text.LastIndexOf(".")) + Str_timeCurrent + "\\" + Str_path + Str_timeCurrent + ".docx";//保存為Word2003文檔
                                                                                                                                                         // path = "d:\\myWord.doc";//保存為Word2007文檔
                app_Word = new MSWord.ApplicationClass();//初始化
                if (File.Exists((string)path))
                {
                    // File.Delete((string)path);
                }
                //由於使用的是COM 庫,因此有許多變量需要用Missing.Value 代替
                Object Nothing = Missing.Value;
                //新建一個word對象
                document_Word = app_Word.Documents.Add(ref Nothing, ref Nothing, ref Nothing, ref Nothing);
                object format = MSWord.WdSaveFormat.wdFormatDocumentDefault;
                //WdSaveDocument為Word2003文檔的保存格式(文檔后綴.doc)\wdFormatDocumentDefault為Word2007的保存格式(文檔后綴.docx)

                //    OpenDocFile(textBox2.Text.Substring(0, textBox2.Text.LastIndexOf("\\") + 1) + time333 + "\\"+time333+".doc");
               // Origin.DataRange dr = m_targetWks.NewDataRange(0, 0, 0, 2);
                //   gl.DataPlots.Add(dr, Origin.PLOTTYPES.IDM_PLOT_SCATTER);
                for (int i = 0; i < ltl.Count; i++)
                {//從我的自定義數據類型listTupleList中循環讀取數據並作圖
                    m_targetWks.ClearData();
                    //先清空workbook1

                    var tl = ltl[i];
                    double[,] data = new double[tl.Item1.Count, 4]; //深度5 寬度4 的數組
                    for (int a = 0; a < tl.Item1.Count; a++)
                    {

                        data[a, 0] = tl.Item1[a];///x 賦值數組 這里是重點 給每列數分別賦值
                        data[a, 1] = tl.Item2[a];//y1賦值數組
                        data[a, 2] = tl.Item2[a];//y2賦值數組
                        data[a, 3] = tl.Item3[a];//y2賦值數組
                    }
                    m_targetWks.SetData(data, -1, 0); // -1 for append row, 0 for first column

                    Origin.GraphPage gp = App.GraphPages["Graph1"];
                    if (null != gp)
                    {
                        gl = (Origin.GraphLayer)gp.Layers[0];
                        //獲取第一個圖層為要修改的層
                        if (null != gl)
                        {

                            var max = maxValue2(tl.Item2.ToArray(), tl.Item3.ToArray());
                            var min = minValue2(tl.Item2.ToArray(), tl.Item3.ToArray());
                            var xmax = maxValue2(tl.Item1.ToArray(), tl.Item1.ToArray());
                            var xmin = minValue2(tl.Item1.ToArray(), tl.Item1.ToArray());
                            //   int inc=   100* Convert.ToInt32(max / 100);
                            string minRate = (min - 0.15 * (max - min)).ToString();
                            string maxRate = (max + (max - min) * 0.55).ToString();
                            string minAxis = (xmin - 0.1 * (xmax - xmin)).ToString();
                            string maxAxis = (xmax + (xmax - xmin) * 0.1).ToString();

                            //下面使用暴力窮舉法調整刻度,解決問題最重要,算法想了很久想不出來 —— ——#
                            int inc = 40;
                            if (max > 100)
                            {
                                inc = 40;
                            }
                            if (max > 200)
                            {
                                inc = 60;
                            }
                            if (max > 400)
                            {
                                inc = 120;
                            }
                            if (max > 800)
                            {
                                inc = 220;
                            }

                            if (max > 1500)
                            {
                                inc = 400;
                            }
                            if (max > 2500)
                            {
                                inc = 500;
                            }
                            if (max > 2500)
                            {
                                inc = 600;
                            }
                            if (max > 4000)
                            {
                                inc = 1000;
                            }
                            if (max > 8000)
                            {
                                inc = 2000;
                            }


                            int incx = 2;
                            if (max > 10)
                            {
                                inc = 4;
                            }
                            if (max > 50)
                            {
                                inc = 10;
                            }
                            if (max > 200)
                            {
                                inc = 50;
                            }
                            if (max > 400)
                            {
                                inc = 120;
                            }

                            //每個對象都有 Execute函數 用來執行 LabTalk函數。
                            gl.Execute("layer.x.from =" + minAxis + ";" + "layer.x.to = " + maxAxis + ";");
                            gl.Execute("layer.y.from =" + minRate + ";layer.y.to =" + maxRate + ";");
                            gl.Execute("layer.y.inc = " + inc.ToString() + ";");
                            gl.Execute("layer.x.inc = " + incx.ToString() + ";");


                            gl.Execute("laylink igl:=1 destlayers:=2:0 XAxis:=1;");
                            gl.Execute("laylink igl:=1 destlayers:=2:0 YAxis:=1;");
                            // Setup the Y axis to auto adjust the scale to fit any data
                            // points that are less than or greater than the scale's range.
                            //   gl.Execute("layer.disp = layer.disp | hex(1000);");
                            //  gl.Execute("label - n text " + "Slope"  + ";");

                            gl.Execute("label - n text " + @"slope\(61)" + tl.Item5[1].ToString("#0.00000") + ";");
                            gl.Execute("label - n text1 " + @"R\+(2)\(61)" + tl.Item5[2].ToString("#0.00000") + ";");
                            gl.Execute("label - n text2 " + @"p\(61)" + tl.Item5[3].ToString("#0.00000") + ";");
                            gl.Execute("label - n XB " + tl.Item4[1] + ";");

                            // \(61)這個寫法是Lable 說明里的 ascii碼寫法
                            string s = textBox2.Text.Substring(0, textBox2.Text.LastIndexOf(".")) + Str_timeCurrent + "\\" + tl.Item4[0] + ".opj";
                            word.Paragraph para1 = document_Word.Content.Paragraphs.Add(ref Nothing);
                            str_Content = tl.Item4[0] + "\n";
                            para1.Range.Text = str_Content;
                            word.Paragraph para = document_Word.Content.Paragraphs.Add(ref Nothing);

                            App.Save(s);
                            Delay_my(1000);
                            gl.Execute("clipboard");
                            para.Range.Paste();
                            //   para.Range.Text = "\n";
                            Delay_my(1000);
                            para.Range.InsertParagraphAfter();//添加一次回車

                            //   App.Save(s);
                            //將wordDoc 文檔對象的內容保存為DOC 文檔,並保存到path指定的路徑
                            document_Word.SaveAs(ref path, ref format, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing);


                        }


                    }
                }


                //     object format = MSWord.WdSaveFormat.wdFormatDocumentDefault;

                //將wordDoc 文檔對象的內容保存為DOC 文檔,並保存到path指定的路徑
                document_Word.SaveAs(ref path, ref format, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing);
                //關閉wordDoc文檔
                document_Word.Close(ref Nothing, ref Nothing, ref Nothing);
                //關閉wordApp組件對象
                app_Word.Quit(ref Nothing, ref Nothing, ref Nothing);

            }
        }

 

  public double maxValue2(double[] s, double[] s2)
        {
            double temp = s[0];
            for (int i = 0; i < s.Length; i++)
            {
                if (temp <= s[i])
                {
                    temp = s[i];
                }
            }

            double temp2 = s[0];
            for (int i = 0; i < s2.Length; i++)
            {
                if (temp2 <= s2[i])
                {
                    temp2 = s2[i];
                }
            }
            if (temp >= temp2)
            {
                return (temp);
            }

            else
            {
                return (temp2);
            }

        }

        public double minValue2(double[] s, double[] s2)
        {
            double temp = s[0];
            for (int i = 0; i < s.Length; i++)
            {
                if (temp >= s[i])
                {
                    temp = s[i];
                }
            }

            double temp2 = s[0];
            for (int i = 0; i < s2.Length; i++)
            {
                if (temp2 >= s2[i])
                {
                    temp2 = s2[i];
                }
            }
            if (temp <= temp2)
            {
                return (temp);
            }

            else
            {
                return (temp2);
            }

        }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM