itext pdf 合并会翻转方向的问题. 修复方法.

itext pdf 合并会翻转方向的问题. 修复方法.

itext pdf 在处理合并多个页面的时候.
有两种方法
一种是直接用itext 的Write 控制输出.
另外一种方法是使用 PdfCopy 类进行复制..

自己用Write控制还算可以.一般都是下面这样写.

 public static MemoryStream mergePDFStream(MemoryStream[] files, iTextSharp.text.Rectangle pagesize = null)
        {
            //outMergeFile = Server.MapPath(outMergeFile);
            //if (outMergeFile == null)
            //{ 
            //    outMergeFile = "d:\\" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + new Random().Next(1000) + ".pdf";
            //} 
            PdfReader reader;
            Document document;
            if (pagesize == null)
            {
                document = new Document();
                //pagesize = PageSize.A4;
            }
            else
            {
                document = new Document(pagesize);
            }
            //var fs = new FileStream(outMergeFile, FileMode.Create);
            MemoryStream fs = new MemoryStream();
            //BufferedStream bfs = new BufferedStream(fs);
            PdfWriter writer = PdfWriter.GetInstance(document, fs);
            writer.CloseStream = false; //不自动关闭内存流. 
            document.Open();
            PdfContentByte cb = writer.DirectContent;
            for (int i = 0; i < files.Length; i++)
            {
                reader = new PdfReader(files[i].ToArray());

                //关闭内存流.
                files[i].Close();


                int iPageNum = reader.NumberOfPages;

                for (int j = 1; j <= iPageNum; j++)
                {

                    PdfImportedPage newPage = writer.GetImportedPage(reader, j);

                    //cb.Add(newPage);
                    //cb.MoveTo(0, 0);
                    // PageSize.A4.Height - newPage.Height 解决itext 高度的问题. itext 的y 轴默认是从下面开始
                    if (pagesize == null)
                    {
                        // newPage.Height;
                        var newPageSize = new iTextSharp.text.Rectangle(newPage.Width, newPage.Height);
                        document.SetPageSize(newPageSize); //这句话使得每页都跟原纸张大小一致.
                        document.NewPage();
                        cb.AddTemplate(newPage, 0, 0);
                    }
                    else
                    {
                        document.SetPageSize(pagesize);
                        document.NewPage();
                        cb.AddTemplate(newPage, 0, pagesize.Height - newPage.Height); //- newPage.Height 解决itext 高度的问题. itext 的y 轴默认是从下面开始 减的目的是使其向上对齐.
                        //cb.AddTemplate(newPage, 1f, 0, 0, 1f, 0, pagesize.Height);
 //                        case 0:
 // writer.DirectContent.AddTemplate(importedPage, 1f, 0, 0, 1f, 0, 0);
 //                       break;
 //case 90:
 // writer.DirectContent.AddTemplate(importedPage, 0, -1f, 1f, 0, 0, pageHeight);
 //                       break;
 //case 180:
 // writer.DirectContent.AddTemplate(importedPage, -1f, 0, 0, -1f, pageWidth, pageHeight);
 //                       break;
 //case 270:
 // writer.DirectContent.AddTemplate(importedPage, 0, 1f, -1f, 0, pageWidth, 0);
 //                       break;
 //                       default:
                    }
                }
                //reader.Close();
            }
            document.Close();
            //byte[] fileBuffer = fs.GetBuffer();

            return fs;
        }

但是上面的这个方法是有问题的. 无论怎么改都不能解决翻转问题. 估计是
cb.AddTemplate(newPage, 0, pagesize.Height - newPage.Height);
没用对, 后面再研究.

第二种使用PdfCopy的方法一般都是下面这样写的.

  public static PdfMemoryStream mergePDFFiles(string[] fileList)
        {
            //outMergeFile = Server.MapPath(outMergeFile);
            //if (outMergeFile == null)
            //{ 
            //    outMergeFile = "d:\\" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + new Random().Next(1000) + ".pdf";
            //} 
            PdfReader reader = null;
            Document document = new Document();

            PdfMemoryStream fs = new PdfMemoryStream();
            fs.AllowClose = false;

            PdfCopy p = new PdfSmartCopy(document, fs); // 生成的目标PDF文件

            document.Open();  

            for (int i = 0; i < fileList.Length; i++)
            {
                try
                {
                     //var fs = new FileStream(outMergeFile, FileMode.Create);  
                    reader = new PdfReader(fileList[i]); // 读取源文件 

                    int n = reader.NumberOfPages; // 获取源文件的页数
                    PdfDictionary pd;
                    for (int j = 1; j <= n; j++)
                    {
                        pd = reader.GetPageN(j);
                        //pd.Put(PdfName.ROTATE, new PdfNumber(90)); // 顺时针旋转90°
                    }
                    for (int page = 0; page < n; )
                    {
                        p.AddPage(p.GetImportedPage(reader, ++page));
                    }

                    reader.Close();//这里需要关闭. 否则会占着文件不释放.
                } 
                catch (Exception ex)
                { 
                    throw new Exception("打开原始PDF文档失败,文件路径为:" + fileList[i], ex);
                }

            }

            document.Close();

            //byte[] fileBuffer = fs.GetBuffer(); 

            return fs;
        }

这第二种方法也是不行的..经过很长时间的猜测和实验, 发现这种方法也是解决不了问题的….从A5变成A4的时候总是会翻转掉….

经过4天的苦战和尝试, 最后终于搞定了.
我这种方法只适合目标大小确定的情况. 如果目标大小不确定的, 还需要再考虑其它方法

        /// <summary> 合併PDF檔(集合)改进版,不会翻转内容 </summary>
        /// <param name="files">欲合併PDF檔之集合(一筆以上)</param> 
        /// <param name="pagesize">纸张大小</param>
        /// <param name="logo">报告单上的logo</param>
        public static MemoryStream mergePDFStream(Stream[] files, iTextSharp.text.Rectangle pagesize = null, LogoImgConfig logo = null)
        {
            Document document;
            if (pagesize == null)
            {
                document = new Document();
                //pagesize = PageSize.A4;
            }
            else
            {
                document = new Document(pagesize);
            }

            //var fs = new FileStream(outMergeFile, FileMode.Create); 

            PdfMemoryStream fs = new PdfMemoryStream();
            fs.AllowClose = false;

            //PdfCopy pcopy = new PdfSmartCopy(document, fs); // 生成的目标PDF文件 
            //pcopy.ChangePageSize(pagesize);

            PdfWriter write = PdfWriter.GetInstance(document, fs);
            write.CloseStream = false; //不自动关闭内存流. 

            document.Open();

            //document.NewPage();
            PdfContentByte cb = write.DirectContent;

            for (int i = 0; i < files.Length; i++)
            {
                try
                {
                    //File.AppendAllText("d:\\ttt.txt", "***** 开始处理第" + i + "个文件******\r\n");

                    //var fs = new FileStream(outMergeFile, FileMode.Create);  
                    PdfReader reader = new PdfReader(files[i]); // 读取源文件 

                    //var pdfVersion = reader.PdfVersion;
                    //var pdfVersion = reader.PdfVersion;
                    //PdfDictionary res = (PdfDictionary)PdfReader.GetPdfObject(pg.Get(PdfName.RESOURCES));
                    //PdfDictionary xobj = (PdfDictionary)PdfReader.GetPdfObject(res.Get(PdfName.XOBJECT));

                    //reader.get
                    //var v = reader.Catalog.Get(PdfName.VERSION);
                    iTextSharp.text.Image logoimg = null;
                    /*增加LOGO图片.*/
                    if (logo != null)
                    {
                        //newPage.AddImage();
                        //创建一个logo图片对象                    
                        logoimg = iTextSharp.text.Image.GetInstance(logo.ImgUri);
                        //logoimg.BackgroundColor = BaseColor.RED;
                        //logoimg.Border = 1;
                        //logoimg.BorderColor = BaseColor.RED;
                        logoimg.ScaleToFit(new iTextSharp.text.Rectangle(logo.Width, logo.Height));

                        //设置图片的指定大小
                        //img.ScaleToFit(140F, 320F);
                        //img.Rotation = rotation;
                        //按比例缩放
                        //img.ScalePercent(50);
                        // logoimg.PlainHeight == logo.Height 是一样的.
                        logoimg.SetAbsolutePosition(logo.Left, pagesize.Height - logo.Height - logo.Top);//y轴的原点在左下角.

                    }

                    //img.Width = 50;
                    //img.SetAbsolutePosition(10, 20);
                    //img.Rotation = 270;
                    //write.DirectContent.AddImage(img);

                    int n = reader.NumberOfPages; // 获取源文件的页数 
                    for (int pageIndex = 1; pageIndex <= n; pageIndex++)
                    {
                        // var Rotation = reader.GetPageRotation(pageIndex); 
                        //var pd = reader.GetPageN(pageIndex);
                        //pd.Put(PdfName.ROTATE, new PdfNumber(90)); //先修改参数内容, 后面再GetImportedPage

                        var newPage = write.GetImportedPage(reader, pageIndex);

                        //if (pdfVersion <= '3') //1.3版 或者以前的版本 坐标系统是不一样的.要旋转90度.
                        //if (newPage.Height == pagesize.Width) //这种写法容错性比较差会有小数部分 改成下面的.
                        //如果老的纸张高度等于目标纸张的宽度,那么直接旋转90度. 例如A5的高度 等于A4的宽度.
                        //

                        if (Math.Abs(newPage.Height - pagesize.Width) < 5)
                        {
                            document.NewPage();
                            document.SetPageSize(pagesize); //这句话使得每页都跟原纸张大小一致.  
                            cb.AddTemplate(newPage, 0, -1, 1, 0, 0, pagesize.Height, true, true);// 0,-1,1,0, 用来旋转pdf内容   
                                                                                                 // 把图片增加到内容页的指定位子  b width c height  e bottom f left
                                                                                                 // cb.AddImage(img, 0, 32F, 32F, 0, 50F, 20);
                                                                                                 //write.DirectContent.AddImage(img);         //添加图片   
                        }
                        else //4,5,6,7
                        {
                            document.NewPage();
                            document.SetPageSize(pagesize); //这句话使得每页都跟原纸张大小一致. 

                            cb.AddTemplate(newPage, 0, pagesize.Height - newPage.Height);

                            // 把图片增加到内容页的指定位子  b width c height  e bottom f left

                            //write.DirectContent.AddImage(img);         //添加图片   
                        }

                        // 把图片增加到内容页的指定位子 b width c height  e bottom f left
                        //cb.AddImage(img, 0, 100, 100, 0, 10, 10); 
                        if (logo != null)
                        {   //这个添加图片必须在复制完页面的下面.
                            cb.AddImage(logoimg);
                        }
                    }

                    logoimg = null;
                    //reader.Close();//这里需要关闭. 否则会占着文件不释放.
                }
                catch (Exception ex)
                {
                    throw new Exception("解析原始PDF文档失败,文件路径为:" + files[i], ex);
                }

            }

            if (document.IsOpen())
            {
                document.Close();
            }


            //fs.Close();
            //byte[] fileBuffer = fs.GetBuffer();
            fs.Position = 0; //使指针指向第一位.
            return fs;
        }
  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值