BigCong 发表于 2023-7-15 11:10

打印机SPL文件提取

为了方便管理打印机文件,提取打印机EMF文件,C#:
核心函数代码如下:
class Program
    {
      //用一个列表记录一个SPL文件中所有EMF文件的起始位置
      private static List<int> _startIndexs;
      //用一个列表记录一个SPL文件中所有EMF文件的数据大小
      private static List<int> _emfDataCount;
         private static void FindEmf(string srcFilePath)
      {
            //初始化两个用来记录EMF文件开始位置和大小的列表
            _startIndexs = new List<int>();
            _emfDataCount = new List<int>();
            //读取SPL文件
            using (FileStream fsR = new FileStream(srcFilePath, FileMode.Open, FileAccess.Read))
            {
                //设置一个20M的字节数组作为缓存区来记录读取的数据
                byte[] buffer = new byte;
                int i = fsR.Read(buffer, 0, buffer.Length);
                //当SPL文件超过20M时,需要读取多遍来记录数据,whileCount用来记录读取的遍数
                int whileCount = -1;
                bool flag = false;
                bool flagB = false;
                //当i=0时,说明已经读取完SPL文件
                while (i > 0)
                {
                  whileCount++;
                  //遍历缓存区数组
                  for (int j = 0; j < i; j++)
                  {
                        if (!flag)
                        {
                            if (j <= 20 * 1024 * 1024-12)
                            {
                              if (j % 4 == 0)
                              {
                                    //找到“0C 00 00 00 XX XX XX XX 01 00 00 00”
                                    if (buffer == 12 && buffer == 0 && buffer == 0 && buffer == 0 && buffer == 1 && buffer == 0 && buffer == 0 && buffer == 0)
                                    {
                                        //记录emf起始位置
                                        _startIndexs.Add(whileCount *( 20 * 1024 * 1024) + j + 8);
                                        //记录emf大小
                                        _emfDataCount.Add((buffer) * 256 * 256 * 256 + (buffer) * 256 * 256 + (buffer) * 256 + (buffer));

                                    }
                              }
                            }
                            else
                            {
                              //当“0C 00 00 00”在数组倒数第二个单位时,需要判断循环读取第二遍时数组第一个单位是否是“01 00 00 00”
                              if (j == 20 * 1024 * 1024-8)
                              {
                                    if (buffer == 12 && buffer == 0 && buffer == 0 && buffer == 0)
                                    {
                                        //记录emf起始位置
                                        _startIndexs.Add(whileCount * (20 * 1024 * 1024) + j + 8);
                                        //记录emf大小
                                        _emfDataCount.Add((buffer) * 256 * 256 * 256 + (buffer) * 256 * 256 + (buffer) * 256 + (buffer));
                                        flag = true;
                                        flagB = true;
                                    }
                              }
                              //当“0C 00 00 00”在数组倒数第一个单位时,需要判断循环读取第二遍时数组第二个单位是否是“01 00 00 00”
                              if (j == 20 * 1024 * 1024-4)
                              {
                                    if (buffer == 12 && buffer == 0 && buffer == 0 && buffer == 0)
                                    {
                                        //记录emf起始位置
                                        _startIndexs.Add(whileCount * (20 * 1024 * 1024) + j + 8);
                                        flag = true;
                                    }
                              }
                            }
                        }
                        //在上一次循环中,“0C 00 00 00”在数组倒数第二个单位或者倒数第一个单位时
                        //需要判断此次循环读取数组第一个单位或者第二个单位是否是“01 00 00 00”
                        else
                        {
                            flag = false;
                            if (_startIndexs.Count == _emfDataCount.Count)
                            {
                              if (!(buffer == 1 && buffer == 0 && buffer == 0 && buffer == 0))
                              {
                                    _startIndexs.RemoveAt(_startIndexs.Count - 1);
                                    _emfDataCount.RemoveAt(_emfDataCount.Count - 1);
                              }
                            }
                            else
                            {
                              if (flagB)
                              {
                                    flagB = false;
                                    _startIndexs.RemoveAt(_startIndexs.Count - 2);
                                    _emfDataCount.RemoveAt(_emfDataCount.Count - 1);
                              }

                              if (!(buffer == 1 && buffer == 0 && buffer == 0 && buffer == 0))
                              {
                                    _startIndexs.RemoveAt(_startIndexs.Count - 1);
                              }
                              else
                              {
                                    _emfDataCount.Add((buffer) * 256 * 256 * 256 + (buffer) * 256 * 256 + (buffer) * 256 + (buffer));
                              }


                            }
                        }

                  }
                  //如果SPL文件没读完,则继续读第二遍,直到读完
                  i = fsR.Read(buffer, 0, buffer.Length);
                }
            }
      }


       public static void SplToEmf(string srcFilePath, string dstFilePath)
         {
             //找到当前SPL文件中所有EMF文件的开始位置和数据大小
             FindEmf(srcFilePath);
             //遍历记录EMF文件开始位置的列表,从而读取所有EMF文件
             for (int j = 0; j < _startIndexs.Count; j++)
             {
               //读取SPL文件
               using (FileStream fsR = new FileStream(srcFilePath, FileMode.Open, FileAccess.Read))
               {
                     //用20M的字节数组作为缓存区读取SPL文件
                     byte[] buffer = new byte;
                     //将读取到的EMF文件数据记录下来
                     using (FileStream fsW = new FileStream(Path.Combine(dstFilePath, Path.GetFileNameWithoutExtension(srcFilePath) + "-" + j.ToString() + ".emf"), FileMode.Create, FileAccess.Write))
                     {
                         int i = fsR.Read(buffer, 0, buffer.Length);
                         int startIndex = _startIndexs;
                         int emfDataCount = _emfDataCount;
                         int X = startIndex;
                         //remnant记录剩余没读完的EMF数据
                         int remnant = emfDataCount;
                         //remnant剩余数据为0时读完一个EMF文件数据
                         while (remnant > 0)
                         {
                           //当EMF文件的起始位置在20M的缓存区内时,开始读取
                           //否则循环读取SPL文件,在下一个缓存中开始找开始位置
                           if (startIndex <= 20 * 1024 * 1024 - 1)
                           {
                                 if (remnant > i - X)
                                     fsW.Write(buffer, X, i - X);
                                 else
                                     fsW.Write(buffer, X, remnant);
                                 remnant = remnant - (i - X);
                                 i = fsR.Read(buffer, 0, buffer.Length);
                                 X = 0;
                           }
                           else
                           {
                                 i = fsR.Read(buffer, 0, buffer.Length);
                                 startIndex = startIndex - 20 * 1024 * 1024;
                                 X = 0;
                           }
                         }
                     }
               }
             }
         }

nodmail 发表于 2023-7-15 11:29

非专业人员,完全没看懂。

dg5988143 发表于 2023-7-15 12:30

学习一下,认真了解中。

xingdongpai 发表于 2023-7-15 13:03

这个怎么用啊,可以提取标签打印机的模板吗

zhoutil 发表于 2023-7-15 13:21

nodmail 发表于 2023-7-15 11:29
非专业人员,完全没看懂。

啊啊啊~~没看懂+1

qingne0130 发表于 2023-7-15 13:55

虽然我没看懂 但是还是要表扬你

稻海香 发表于 2023-7-15 15:59

看不懂,但还是要竖起拇指表扬下

yellowchristmas 发表于 2023-7-15 16:53

学习了,谢谢版主!!!

tp206555 发表于 2023-7-15 20:50

表示没看懂学习

xls113355 发表于 2023-7-16 10:58

在学习中进步成长
页: [1]
查看完整版本: 打印机SPL文件提取