⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ole2document.cs

📁 Excel的操作,其中可以读取及写入Excel 文件
💻 CS
📖 第 1 页 / 共 2 页
字号:
			stream.Read(head, 0, 512);

			bool isLE = false;
			if (head[28] == 254 && head[29] == 255)
				isLE = true;

			if (!isLE)
				throw new NotSupportedException("File is not Little-Endian");
			_isLittleEndian = isLE;

			ushort sectorSize = BitConverter.ToUInt16(MidByteArray(head, 30, 2), 0);
			if (sectorSize < 7 || sectorSize > 32)
				throw new Exception(string.Format("Invalid Sector Size [{0}] (should be 7 <= sectorSize <= 32", sectorSize));
			_sectorSize = sectorSize;

			ushort shortSectorSize = BitConverter.ToUInt16(MidByteArray(head, 32, 2), 0);
			if (shortSectorSize > sectorSize)
				throw new Exception(
					string.Format("Invalid Short Sector Size [{0}] (should be < sectorSize; {1})", shortSectorSize, sectorSize));
			_shortSectorSize = shortSectorSize;

			//if (readError) ExitFunction;

			uint satSectorCount = BitConverter.ToUInt32(MidByteArray(head, 44, 4), 0);
			if (satSectorCount < 0)
				throw new Exception(string.Format("Invalid SAT Sector Count [{0}] (should be > 0)", satSectorCount));

		    int dirSID0 = BitConverter.ToInt32(MidByteArray(head, 48, 4), 0);
            if (dirSID0 < 0)
                throw new Exception(string.Format("Invalid Directory SID0 [{0}] (should be > 0)", dirSID0));

		    uint minStandardStreamSize = BitConverter.ToUInt32(MidByteArray(head, 56, 4), 0);
            if ((minStandardStreamSize < (Math.Pow(2, sectorSize))) || (minStandardStreamSize % (Math.Pow(2, sectorSize)) > 0))
                throw new Exception(string.Format("Invalid MinStdStreamSize [{0}] (should be multiple of (2^SectorSize)", minStandardStreamSize));
		    _standardStreamMinBytes = minStandardStreamSize;

		    int ssatSID0 = BitConverter.ToInt32(MidByteArray(head, 60, 4), 0);
		    uint ssatSectorCount = BitConverter.ToUInt32(MidByteArray(head, 64, 4), 0);
            if (ssatSID0 < 0 && ssatSID0 != -2)
                throw new Exception(string.Format("Invalid SSAT SID0 [{0}] (must be >=0 or -2", ssatSID0));
            if (ssatSectorCount > 0 && ssatSID0 < 0)
                throw new Exception(
                    string.Format("Invalid SSAT SID0 [{0}] (must be >=0 when SSAT Sector Count > 0)", ssatSID0));
            if (ssatSectorCount < 0)
                throw new Exception(string.Format("Invalid SSAT Sector Count [{0}] (must be >= 0)", ssatSectorCount));

		    int msatSID0 = BitConverter.ToInt32(MidByteArray(head, 68, 4), 0);
            if (msatSID0 < 1 && msatSID0 != -2)
                throw new Exception(string.Format("Invalid MSAT SID0 [{0}]", msatSID0));

		    uint msatSectorCount = BitConverter.ToUInt32(MidByteArray(head, 72, 4), 0);
            if (msatSectorCount < 0)
                throw new Exception(string.Format("Invalid MSAT Sector Count [{0}]", msatSectorCount));
            else if (msatSectorCount == 0 && msatSID0 != -2)
                throw new Exception(string.Format("Invalid MSAT SID0 [{0}] (should be -2)", msatSID0));

		    int i = 0;
		    int k = ((int)Math.Pow(2, sectorSize) / 4) - 1;
		    int[] msat = new int[108 + (k * msatSectorCount) + 1]; //add 1 compared to VBScript version due to C#/VBS array declaration diff
            for (int j = 0; j < 109; j++)
                msat[j] = BitConverter.ToInt32(MidByteArray(head, 76 + (j * 4), 4), 0);
		    int msatSidNext = msatSID0;
            while (i < msatSectorCount)
            {
                Bytes sector = GetSector(stream, sectorSize, msatSidNext);
                if (sector.Length == 0)
                    throw new Exception(string.Format("MSAT SID Chain broken - SID [{0}] not found / EOF reached", msatSidNext));
                for (int j = 0; j < k; j++)
                    msat[109 + (i * k) + j] = BitConverter.ToInt32(sector.Get(j * 4, 4).ByteArray, 0);
                msatSidNext = BitConverter.ToInt32(sector.Get(k * 4, 4).ByteArray, 0);
                i++;
            }

            //if (re) Exit Function;

            //Find number of Sectors in SAT --> i
		    i = msat.Length;
            while (msat[i - 1] < 0)
                i--;

            //Size and fill SAT SID array
		    int[] sat = new int[(uint) (i * (Math.Pow(2, sectorSize) / 4))];
		    int m = (int)(Math.Pow(2, sectorSize) / 4);
            for (int j = 0; j < i; j++)
            {
                Bytes sector = GetSector(stream, sectorSize, msat[j]);
                if (sector.Length == 0)
                    throw new Exception(string.Format("SAT SID Chain broken - SAT Sector SID{0} not found / EOF reached", msat[j]));
                for (k = 0; k < m; k++)
                    sat[(j * m) + k] = BitConverter.ToInt32(sector.Get(k * 4, 4).ByteArray, 0);
            }

            //Size and fill SSAT SID array
		    i = 0;
		    int ssatSidNext = ssatSID0;
//		    m = (int) (Math.Pow(2, sectorSize) / 4);
		    //Dictionary<int, int> ssat = new Dictionary<int, int>();
		    int[] ssat = new int[(ssatSectorCount + 1) * m];
            while (ssatSidNext > -2)
            {
                Bytes sector = GetSector(stream, sectorSize, ssatSidNext);
                if (sector.Length == 0)
                    throw new Exception(string.Format("SSAT Sector SID{0} not found", ssatSidNext));
                for (int j = 0; j < m; j++)
                    ssat[(i * m) + j] = BitConverter.ToInt32(sector.Get(j * 4, 4).ByteArray, 0);
                ssatSidNext = sat[ssatSidNext];
                i++;
            }
            if (i < ssatSectorCount)
                throw new Exception(string.Format("SSAT Sector chain broken: {0} found, header indicates {1}", i, ssatSectorCount));

            //Size and fill Directory byte array array
		    int dirSectorCount = 0;
		    int dirSidNext = dirSID0;
		    m = (int) (Math.Pow(2, sectorSize) / 128);
		    Dictionary<int, byte[]> dir = new Dictionary<int, byte[]>();
            while (dirSidNext > -2)
            {
                Bytes sector = GetSector(stream, sectorSize, dirSidNext);
                if (sector.Length == 0)
                    throw new Exception(string.Format("Directory Sector SID{0} not found", dirSidNext));
                for (int j = 0; j < m; j++)
                    dir[(dirSectorCount * m) + j] = sector.Get(j * 128, 128).ByteArray;
                dirSidNext = sat[dirSidNext];
                dirSectorCount++;
            }

            for (i = 0; i < dir.Count; i++)
            {
                byte[] dirEntry = dir[i];
                int nameLength = BitConverter.ToInt16(MidByteArray(dirEntry, 64, 2), 0);
                byte[] docStreamName = MidByteArray(dirEntry, 0, nameLength);
                bool overwrite = false;
                if (Bytes.AreEqual(docStreamName, Directory.RootName))
                    overwrite = true;
                Bytes docStream =
                    GetStream(stream, i, dir, sectorSize, sat, shortSectorSize, ssat, minStandardStreamSize);
                Streams.AddNamed(docStream, docStreamName, overwrite);
            }

		}

        private Bytes GetStream(System.IO.Stream fromDocumentStream, int did, Dictionary<int, byte[]> dir, ushort sectorSize, int[] sat, ushort shortSectorSize, int[] ssat, uint minStandardStreamSize)
        {
            Bytes stream = new Bytes();
            Bytes fromBytes;
            int[] fromSAT;
            ushort fromSectorSize;
            Bytes sector;
            int sidNext;
            string shortness;

            int streamLength = BitConverter.ToInt32(MidByteArray(dir[did], 120, 4), 0);

            Bytes streamBytes = null;
            byte[] streamByteArray;

            if (did == 0 || (streamLength >= minStandardStreamSize))
            {
                streamByteArray = new byte[fromDocumentStream.Length];
                fromDocumentStream.Position = 0;
                fromDocumentStream.Read(streamByteArray, 0, streamByteArray.Length);
                streamBytes = new Bytes(streamByteArray);
            }

            if (did == 0)
            {
                fromSectorSize = sectorSize;
                fromSAT = sat;
                shortness = string.Empty;
                fromBytes = streamBytes;
            }
            else if (streamLength < minStandardStreamSize)
            {
                fromSectorSize = shortSectorSize;
                fromSAT = ssat;
                shortness = "Short ";
                fromBytes = GetStream(fromDocumentStream, 0, dir, sectorSize, sat, shortSectorSize, ssat, minStandardStreamSize);
            }
            else
            {
                fromSectorSize = sectorSize;
                fromSAT = sat;
                shortness = string.Empty;
                fromBytes = streamBytes;
            }

            sidNext = BitConverter.ToInt32(MidByteArray(dir[did], 116, 4), 0);
            while (sidNext > -2)
            {
                if (did > 0 && streamLength < minStandardStreamSize)
                    sector = GetShortSectorBytes(fromBytes, fromSectorSize, sidNext);
                else
                    sector = GetSectorBytes(fromBytes, fromSectorSize, sidNext);

                if (sector.Length == 0)
                    throw new Exception(string.Format("{0}Sector not found [SID{1}]", shortness, sidNext));

                stream.Append(sector);

                sidNext = fromSAT[sidNext];
            }

            return stream.Get(streamLength);
        }

	    private static Bytes GetSectorBytes(Bytes fromStream, int sectorSize, int sid)
	    {
	        int i = (int) Math.Pow(2, sectorSize);
            
            if (fromStream.Length < (sid * i))
                throw new Exception(string.Format("Invalid SID [{0}] (EOF reached)", sid));

	        return fromStream.Get(512 + (sid * i), i);
	    }

	    private static Bytes GetShortSectorBytes(Bytes fromShortSectorStream, int shortSectorSize, int sid)
	    {
	        int i = (int) Math.Pow(2, shortSectorSize);

            if (fromShortSectorStream.Length < (sid * i))
                throw new Exception(string.Format("Invalid SID [{0}] (EOF reached)", sid));

//	        return fromShortSectorStream.Get((sid * i) + 1, i);
            return fromShortSectorStream.Get(sid * i, i);
        }

	    private static Bytes GetSector(System.IO.Stream stream, int sectorSize, int sidIndex)
        {
            int sectorLength = (int) Math.Pow(2, sectorSize);
            int offset = 512 + (sidIndex * sectorLength);
            if (stream.Length < (offset + sectorLength))
                return new Bytes();
            byte[] sector = new byte[sectorLength];
	        stream.Seek(offset, SeekOrigin.Begin);
//            stream.Position = offset;
	        ReadWholeArray(stream, sector);
//            int read = stream.Read(sector, 0, sectorLength);
            return new Bytes(sector);
        }

        /// <summary>
        /// Reads data into a complete array, throwing an EndOfStreamException
        /// if the stream runs out of data first, or if an IOException
        /// naturally occurs.
        /// http://www.yoda.arachsys.com/csharp/readbinary.html
        /// </summary>
        /// <param name="stream">The stream to read data from</param>
        /// <param name="data">The array to read bytes into. The array
        /// will be completely filled from the stream, so an appropriate
        /// size must be given.</param>
        public static void ReadWholeArray(System.IO.Stream stream, byte[] data)
        {
            int offset = 0;
            int remaining = data.Length;
            while (remaining > 0)
            {
                int read = stream.Read(data, offset, remaining);
                if (read <= 0)
                    throw new EndOfStreamException
                        (String.Format("End of stream reached with {0} bytes left to read", remaining));
                remaining -= read;
                offset += read;
            }
        }

        private static byte[] MidByteArray(byte[] byteArray, int offset, int length)
		{
			if (offset >= byteArray.Length)
				throw new ArgumentOutOfRangeException(string.Format("offset {0} must be less than byteArray.Length {1}", offset, byteArray.Length));

			if (offset + length > byteArray.Length)
				throw new ArgumentOutOfRangeException(string.Format("offset {0} + length {1} must be <= byteArray.Length {2}", offset, length, byteArray.Length));

			if (offset == 0 && length == byteArray.Length)
				return byteArray;

			byte[] subArray = new byte[length];
			for (int i = 0; i < length; i++)
				subArray[i] = byteArray[offset + i];
			return subArray;
		}

        /// <summary>
        /// Gets a blank array of bytes.  Included as documented filler field.
        /// </summary>
		public byte[] Blank1
		{
			get { return _blank1; }
		}

        /// <summary>
        /// Gets a blank array of bytes.  Included as documented filler field.
        /// </summary>
		public byte[] Blank2
		{
			get { return _blank2; }
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -