public void Save(string file_name)
        {
            ZipStorer result = ZipStorer.Create(file_name, "");                                                                 // Create the output filename
            Stream    data;                                                                                                     // This will be out stream
            gStream   sst = null;

            foreach (gStream g in streams)                                                                                      // Loop all the streams in the template
            {
                string name = g.zfe.FilenameInZip;                                                                              // This is the stream name
                if (name != "xl/sharedStrings.xml")                                                                             // If this is not the shared strings stream
                {
                    if (!sources.TryGetValue(name, out data))
                    {
                        data = g.ReadAsMemory();                                                                                // Get data stream either from memory or from Sources
                    }
                    result.AddStream(ZipStorer.Compression.Deflate, name, data, DateTime.Now, "");                              // Add to our ZIP file
                }
                else
                {
                    sst = g;
                }
            }
            if (!sources.TryGetValue("xl/sharedStrings.xml", out data))
            {
                data = sst.ReadAsMemory();                                                                                      // Get data stream either from memory or from Sources
            }
            result.AddStream(ZipStorer.Compression.Deflate, "xl/sharedStrings.xml", data, DateTime.Now, "");                    // Add to our ZIP file
            result.Close();                                                                                                     // Close the ZIP file
        }
        /*
         *
         * public bool SaveStream(string StreamName, string FileName)
         * {
         *  gStream f = null;
         *  foreach (gStream s in streams) if (s.zfe.FilenameInZip == StreamName) f = s;
         *  if (f == null) return false;
         *  f.SaveToFile(FileName);
         *  return true;
         * }
         * */

        private void SetStructure()                                                                                             // Initializes all the elements of a valid XLSX file
        {
            XmlDocument rd = null, sd = null, st = null;

            foreach (gStream s in streams)                                                                                      // Loop all the streams and get
            {
                if (s.zfe.FilenameInZip == "xl/_rels/workbook.xml.rels")
                {
                    rd = s.ReadAsXml();                                                                                         //      Stream for Relations
                }
                if (s.zfe.FilenameInZip == "xl/workbook.xml")
                {
                    sd = s.ReadAsXml();                                                                                         //      Stream for structure
                }
                if (s.zfe.FilenameInZip == "xl/sharedStrings.xml")
                {
                    st = s.ReadAsXml();                                                                                         //      Stream for strings
                }
            }
            if ((rd == null) || (sd == null) || (st == null))
            {
                throw new Exception("Bad WorkBook");                                                                            // If ay of them could not be found, then raise an error
            }
            XmlNode tn = st.FirstChild.NextSibling.FirstChild;                                                                  // This is the first node with strings

            while (tn != null)
            {
                words.Add(tn.FirstChild.InnerText); tn = tn.NextSibling;
            }                                                                                                                   // Add all strings to dictionary

            XmlNamespaceManager nsmgr0 = new System.Xml.XmlNamespaceManager(sd.NameTable);                                      // Add namespaces

            nsmgr0.AddNamespace("main", "http://schemas.openxmlformats.org/spreadsheetml/2006/main");
            nsmgr0.AddNamespace("r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
            XmlNamespaceManager nsmgr1 = new System.Xml.XmlNamespaceManager(rd.NameTable);

            nsmgr1.AddNamespace("rels", "http://schemas.openxmlformats.org/package/2006/relationships");

            foreach (XmlNode n in sd.SelectNodes("main:workbook/main:sheets/main:sheet", nsmgr0))                               // For each sheet
            {
                string  rId = n.Attributes["r:id"].Value;                                                                       // Get its RelationID
                XmlNode r   = rd.SelectSingleNode("rels:Relationships/rels:Relationship[@Id='" + rId + "']", nsmgr1);           // Use RelationID to find it in Relations
                if (r != null)                                                                                                  // If found,
                {
                    gStream sr = streams.Find(element => element.zfe.FilenameInZip == "xl/" + r.Attributes["Target"].Value);    // Use Target to find the stream implementing the relation
                    if (sr == null)
                    {
                        throw new Exception("Could not find [" + r.Attributes["Target"].Value + "] in streams");                // Raise and error if fail
                    }
                    sr.Sheet = new gSheet(this, Int32.Parse(n.Attributes["sheetId"].Value), n.Attributes["name"].Value, sr);    // Create the stream structure
                    sheets[sr.Sheet.Name] = sr.Sheet;                                                                           // Add it
                }
            }
        }
 internal gSheet(OoXml d, int i, string n, gStream s)
 {
     Document = d; Index = i;
     Name = n;
     Stream = s;
 }
 internal gSheet(OoXml d, int i, string n, gStream s)
 {
     Document = d; Index = i;
     Name     = n;
     Stream   = s;
 }