文档在线预览:文档生成技术细节

文档在线预览研究系列
总体思路
文档生成技术细节
利用百度阅读器


  之前的“文档在线预览:总体思路”受到很多朋友的欢迎,为此我继续讲一下文档在线预览两个步骤的一些技术细节。以下我以C#语言和Windows平台为例展开做一些介绍。
  请记住,本文讲的是文档转化为pdf再转化为其他格式的方法,不讨论转化成的flash如何展示的问题(暂且假设用FlexPaper来展示吧)。文章后面附带本文讲到的相关操作的源码和软件下载,有些软件需要购买授权才能使用。

四项基本操作
1、调用Windows打印机打印文档
            PrintDocument docToPrint = new PrintDocument();
            docToPrint.DocumentName 
= GetPath(sourcePath);
            
//开始打印
            docToPrint.Print();

 

2、调用命令行执行CMD命令
代码
        /// <summary>
        
/// 运行命令
        
/// </summary>
        
/// <param name="strShellCommand">命令字符串</param>
        
/// <returns>命令运行时间</returns>
        private static double RunShell(string strShellCommand)
        {
            
double spanMilliseconds = 0;
            DateTime beginTime 
= DateTime.Now;

            Process cmd 
= new Process();
            cmd.StartInfo.FileName 
= "cmd.exe";
            cmd.StartInfo.UseShellExecute 
= false;
            cmd.StartInfo.CreateNoWindow 
= true;
            cmd.StartInfo.Arguments 
= String.Format(@"/c {0}", strShellCommand);
            cmd.Start();
            cmd.WaitForExit();


            DateTime endTime 
= DateTime.Now;
            TimeSpan timeSpan 
= endTime - beginTime;
            spanMilliseconds 
= timeSpan.TotalMilliseconds;

            
return spanMilliseconds;
        }

 

 3、检查文件是否生成完毕

代码
        /// <summary>
        
/// 检查是否转换成功(文件是否生成完毕)
        
/// </summary>
        
/// <param name="sourcePath">要检查文件地址</param>
        
/// <param name="targetPath">要复制到的地址(如果不需要真正复制,请跟sourcePath一致)</param>
        
/// <param name="timeout">最大等待时间</param>
        
/// <returns></returns>
        private static bool IsParseSuccess(string sourcePath, string targetPath, int timeout)
        {
            
bool isSuccess = false;

            
if (timeout <= 0)
                timeout 
= 30;

            
int i = 0;
            
while (!RenameFile(sourcePath, targetPath))
            {
                Thread.Sleep(
1000);
                i
++;
                
if (i == timeout)
                    
break;
            }
            
if (i < timeout)
                isSuccess 
= true;

            
return isSuccess;
        }

        
/// <summary>
        
/// 重命名文件(用来检查文件是否生成完成)
        
/// </summary>
        
/// <param name="sourePath">源地址</param>
        
/// <param name="targetPath">目标地址</param>
        
/// <returns></returns>
        private static bool RenameFile(string sourePath, string targetPath)
        {
            
bool isOpen = false;
            
            
//如果是相同地址,直接移动检查是否文件已经生成,否则进行复制(因为目标文件存在的话会有问题)
            if (sourePath.Equals(targetPath))
            {
                
try
                {
                    
//移动文件
                    File.Move(sourePath, targetPath);
                    isOpen 
= true;
                }
                
catch (Exception e)
                {

                }
            }
            
else
            {
                
bool isCopySuccess = false;
                
try
                {
                    
//复制文件
                    File.Copy(sourePath, targetPath, true);
                    isCopySuccess 
= true;
                }
                
catch (Exception e)
                {
                    isCopySuccess 
= false;
                }
                
if (isCopySuccess)
                {
                    
//如果复制成功,删除源文件
                    File.Delete(sourePath);
                }
            }

            
return isOpen;
        }

 

 4、杀掉进行函数

代码
        /// <summary>
        
/// 根据进程名称来关闭进程
        
/// </summary>
        
/// <param name="processName"></param>
        private static void KillPrecess(string processName)
        {
            
foreach (Process p in Process.GetProcesses())
            {
                
if (p.ProcessName == processName)
                {
                    p.Kill();
                }
            } 
        }

 


文档转pdf
  我们介绍的文档转化为pdf的方法,要求是较为通用,即不需要根据具体文档写具体的程序,且不仅要支持Office文档,最好还要支持txt、html等其他文档。

1、使用pdfFactory(见源码方法:ParsePDFWithPdfFactory)
说明:软件需要注册才能使用
原理:
  a. 调用系统默认打印机(pdfFactory)打印文档;
  b. 从打印机的临时目录里将pdf拷贝到目标路径;
pdfFactory的设置:
  a. 打开打印机,设置“pdfFactory Pro”为默认打印机;
  b. 打开“pdfFactory Pro”的“打印机首选项”,在“Licensing”选项卡里注册打印机;
  c. 打开“pdfFactory Pro”的“打印机首选项”,结合程序,进行如下两个图的设置;


 

优点:
  a. 只要支持打印的文件均可以用此法转化为pdf;
不足:
  a. 服务器上经常会弹出文件打印窗口;
  b. 一些损坏的文件或者格式不正确的文档会中止生成过程;
  c. 如果遇到带病毒宏的文档,会对服务器产生破坏;
注意事项:
  a. 打印过程中会产生大量临时文件在用户目录,需要及时清理垃圾文件,或者将对应目录迁移到磁盘空间较大的位置;
  b. Windows Server需要安装Server版pdfFactory;


2、使用FlashPaper(见源码方法:ParsePDFWithFlashPrinter)
原理:调用命令行“flashprinter c:\document.doc -o c:\document.pdf”进行打印;
优点:
  a. 只要支持打印的文件均可以用此法转化为pdf;
  b. 操作简单
不足:
  a. 由于程序本身问题,有时可能导致打印不能结束,几百个进程同时运行拖垮系统的情况;


3、其他方法(未附源码)
  使用其他虚拟打印机,例如:Virtual PDF Printer
  使用jcom或其它方式调用Office的Component进行转化,具体请参考:将office文档(word,excel,powerpoint)转换为pdf
  调用使用JodConverter调用OpenOffice转化,具体请参考:JodConverter实现Office转化PDF格式


pdf转flash(见源码方法:ParseSWF)
原理:使用SWFTools的pdf2swf,调用命令行“pdf2swf.exe -T 9 -p 1-3 -s languagedir=D:\xpdf-3.02pl5\xpdf-chinese-simplified D:\document.pdf -o D:\document.swf”进行转换;

常见问题:
1、部分文档转化后乱码,控制台提示:找不到“Adobe-GB1”字体
解决办法:在pdf2swf命令中带上语言包,详情请看:http://cqfish.blog.51cto.com/622299/163566
2、部分文档可能无法在FlexPaper里无法显示
解决办法:flash版本的问题,在pdf2swf命令中带上参数,设置生成的版本为9(参数为:-T 9),这样兼容性最好。


pdf转图片(见源码方法:ParseCoverImage)
原理:使用“VeryPDF PDF To Image Converter”软件,调用命令行“pdf2img.exe -r 25 -f 1 -l 1 -i c:\1.pdf -o c:\11.jpg ”进行转换;


pdf转文本(见源码方法:ParseText)
有时为了生成摘要或者索引文档内容,需要将文档里的文本读取进来,xpdf是一个不错的工具。
原理:使用“xpdf”软件,调用命令行“pdftotext.exe c:\1.pdf c:\1.txt”进行转化;
常见问题:要让xpdf支持中文,还需要下载中文语言包并做一些配置,xpdf中文化详细配置请参考:http://emily2ly.javaeye.com/blog/743552

本文涉及软件及源码下载:document-preview-online-demo-canbeing.rar

  

反馈文章质量,你可以通过快速通道评论:

 

posted @ 2010-11-27 01:50 canbeing 阅读(4338) 评论(49) 编辑 收藏

 回复 引用 查看   
#1楼 2010-11-27 03:06 yueyue184      
不错的文章,谢谢分享,
 回复 引用 查看   
#2楼 2010-11-27 07:21 woody.wu      
guanzhu
 回复 引用 查看   
#3楼 2010-11-27 07:52 天行健 自强不息      
谢谢分享
 回复 引用 查看   
#4楼 2010-11-27 08:33 长河落日      
学习..
 回复 引用 查看   
#5楼 2010-11-27 09:40 闲聊闲逛      
谢谢,不过文档生成开发过程中还有很多问题需要解决的,问题很多,我一个项目就因为这些弄得很头疼,不过都解决了,谢谢提供那么详细的组件给博园好友。
 回复 引用 查看   
#6楼 2010-11-27 10:16 aitouchy      
ggghgfhgfj
 回复 引用 查看   
#7楼[楼主] 2010-11-27 10:20 canbeing      
飘过~~
 回复 引用 查看   
#8楼 2010-11-27 10:49 longware      
服务器是linux咋办呢???
 回复 引用 查看   
#9楼 2010-11-27 12:09 易木      
文章不错,支持一下!
 回复 引用 查看   
#10楼 2010-11-27 12:22 傻样精英      
飘过~~
 回复 引用 查看   
#11楼 2010-11-27 12:31 bambino      
文章不错,支持一下!
 回复 引用 查看   
#12楼[楼主] 2010-11-27 12:48 canbeing      
@longware
引用longware:服务器是linux咋办呢???

文中开关已经说了是基于C#跟Windows的平台
如果是Linux的话,其实那几个软件也基本有Linux版本的或者替代产品。
而且如果确实不行,你完全可以弄一台Windows服务来专门负责文档转化。

 回复 引用 查看   
#13楼 2010-11-27 14:06 elwin.wang      
飘过~~
 回复 引用 查看   
#14楼 2010-11-27 15:10 雯丽      
谢谢分享!~
 回复 引用 查看   
#15楼 2010-11-27 15:29 Vincent.Q      
还可以,支持一下!
 回复 引用 查看   
#16楼 2010-11-27 17:40 蓝蓝的天      
文章不错,支持一下!
 回复 引用 查看   
#17楼 2010-11-27 18:31 萧寒      
文章不错,支持一下!
 回复 引用 查看   
#18楼 2010-11-27 18:33 风之小子      
文章不错,支持一下!
 回复 引用 查看   
#19楼 2010-11-27 19:37 Leon yang      
文章不错,支持一下!
 回复 引用 查看   
#20楼 2010-11-27 19:37 Leon yang      
飘过~~
 回复 引用 查看   
#21楼 2010-11-27 21:13 Own_nothing      
文章不错,支持一下!
 回复 引用 查看   
#22楼 2010-11-27 22:37 shenzhen      
还可以,支持一下!
 回复 引用 查看   
#23楼 2010-11-28 01:08 ruinet      
文章不错,支持一下!
 回复 引用 查看   
#24楼 2010-11-28 01:17 三桂      
飘过~~
 回复 引用 查看   
#25楼 2010-11-28 08:10 跳舞      
你胡搜。我想请教下几种方法里哪种效率最高,占用内存最小?(第二种用flashpaper不考虑内)
 回复 引用 查看   
#26楼 2010-11-28 08:11 跳舞      
额 打错字了 是“你好”
 回复 引用 查看   
#27楼 2010-11-28 09:52 阿超-      
不及格了~~
 回复 引用 查看   
#28楼 2010-11-28 14:40 gulu      
文章不错,支持一下!
 回复 引用 查看   
#29楼[楼主] 2010-11-28 19:24 canbeing      
@跳舞
引用跳舞:你胡搜。我想请教下几种方法里哪种效率最高,占用内存最小?(第二种用flashpaper不考虑内)

目前我用的是pdfFactory,但不大满意,正在考虑改进

 回复 引用 查看   
#30楼 2010-11-29 10:26 Michaelshen      
一般般,支持一下!
 回复 引用 查看   
#31楼 2010-11-29 10:26 Michaelshen      
好像差点,支持一下!
 回复 引用 查看   
#32楼 2010-11-29 10:26 Michaelshen      
不及格了~~
 回复 引用 查看   
#33楼 2010-11-29 14:06 ★金★      
文章不错,支持一下!
 回复 引用 查看   
#34楼 2010-11-29 17:07 jamin      
支持一下!

 回复 引用 查看   
#35楼 2010-11-29 17:37 失落小羊      
文章不错,支持一下!
 回复 引用 查看   
#36楼 2010-11-29 20:32 跳舞      
哦,如果有改进的方法能不能也拿出来共享一下啊。我是个学生,技术面有限,但对这个文档转换又比较感兴趣,转换文档到pdf格式的方法,能找到的方法就是虚拟机和openoffice。还有哦,转换pdf到swf时用pdf2swf,可当文档稍微大一点,内存占用就有点高了。真诚求解,期待您后面的文章,我几乎每天都来这里看你更新没。之前老赵又一篇文章,额,可惜我看不懂。
 回复 引用 查看   
#37楼 2010-11-30 12:21 麦克刘.Mr      
不及格了~~
 回复 引用 查看   
#38楼 2010-12-02 21:07 yearN      
飘过~~
 回复 引用 查看   
#39楼 2010-12-03 18:59 Macopad      
很好,最近我们也在研究预览的东西。
 回复 引用 查看   
#40楼 2010-12-05 04:29 ※蝶恋花※      
文章不错,支持一下!
 回复 引用 查看   
#41楼 2010-12-05 04:29 ※蝶恋花※      
还可以,支持一下!
 回复 引用 查看   
#42楼 2010-12-08 16:33 大灰狠000      
不错,拿走啦 哈哈
 回复 引用 查看   
#43楼 2010-12-09 15:35 wangwss      
文章不错,支持一下!
 回复 引用 查看   
#44楼 2010-12-10 11:00 无为是最高      
哈哈,感谢楼主分享。
http://admin.mine123.com/ 演示地址,有需要的可以联系!

 回复 引用 查看   
#45楼 2010-12-29 16:53 言学      
真是不错的文章,期待楼主第三篇早日出炉。
 回复 引用 查看   
#46楼 2011-05-09 11:03 jiangty      
文章不错,支持一下!
 回复 引用 查看   
#47楼 2011-06-19 00:32 hyh030      
请问一下楼主,flexpaper怎么自动生成缩略图呢?我看flexpaper在API调试界面有个postSnapshot按钮,但是输入什么字符都没有反应,请帮忙指点下
 回复 引用 查看   
#48楼[楼主] 2011-06-19 09:23 canbeing      
@hyh030
flexpaper只是展示flash用的
可以用pdf2img来实现生成缩略图

 回复 引用 查看   
#49楼 2011-12-23 10:55 Qamar      
请问楼主一下,使用FlashPaper会出现转换不成功的情况,产生大量的excel.exe FlashPriner.exe Winword.exe进程,有什么好的解决办法啊。