| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
共有 1319 人关注过本帖
标题:求助各位大神自动保存问题:测试发现还需要手动输入文件名进行保存,为什么 ...
只看楼主 加入收藏
nybdx
Rank: 1
等 级:新手上路
帖 子:7
专家分:0
注 册:2011-3-22
结帖率:0
收藏
已结贴  问题点数:20 回复次数:15 
求助各位大神自动保存问题:测试发现还需要手动输入文件名进行保存,为什么还要手动指定文件名?
在vfp9环境下,有很多dyzkz_开头的表,分别用作报表dy01tcz.frx的数据环境通过Microsoft Print to PDF虚拟打印机打印输出并自动保存为同文件名的PDF格式文档,DS给出的代码如下:
LOCAL lcTableName, lcPDFFileName, lcReportName, lcPrinterName

* 设置报表文件名
lcReportName = "dy01tcz.frx"

* 设置虚拟打印机名称
lcPrinterName = "Microsoft Print to PDF"

* 获取当前目录下的所有符合要求的表文件
LOCAL ARRAY laTables[1]
ADIR(laTables, "dyzkz_*.dbf")

* 遍历每个表文件
FOR i = 1 TO ALEN(laTables, 1)
    lcTableName = laTables[i, 1]
   
    * 生成对应的 PDF 文件名
    lcPDFFileName = STRTRAN(lcTableName, ".dbf", ".pdf")
   
    * 设置数据环境
    USE (lcTableName) ALIAS tempTable
   
    * 设置默认打印机为 Microsoft Print to PDF
    SET PRINTER TO NAME (lcPrinterName)
   
    * 配置打印机输出路径(需要调用 Windows API 或外部工具)
    * 这里假设你已经通过其他方式配置了虚拟打印机的默认保存路径
   
    * 生成报表并输出为 PDF
    REPORT FORM (lcReportName) TO FILE (lcPDFFileName) NOCONSOLE NOEJECT
   
    * 关闭表
    USE IN tempTable
ENDFOR

代码哪里有问题?
2025-03-04 09:25
csyx
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:火星
等 级:版主
威 望:37
帖 子:735
专家分:2958
注 册:2018-3-13
收藏
得分:4 
以下是引用nybdx在2025-3-4 09:25:52的发言:
    * 生成报表并输出为 PDF
    REPORT FORM (lcReportName) TO FILE (lcPDFFileName) NOCONSOLE NOEJECT

基本没用过 vfp 的报表,不过印象中 [TO FILE ...] 是输出为 ASCII 文本文件

这家伙很懒,啥也没留下
2025-03-04 19:24
sam_jiang
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:14
帖 子:865
专家分:1357
注 册:2021-10-13
收藏
得分:4 
回复 2楼 csyx
楼上解释合理,文件名并没有传递给打印机,也就是说to file cfilname不对,你可以问一下ds,怎么把文件名作文为参数传递给打印机?
2025-03-04 20:53
nybdx
Rank: 1
等 级:新手上路
帖 子:7
专家分:0
注 册:2011-3-22
收藏
得分:0 
谢谢两位!ds弄了很长时间也不行
2025-03-05 15:33
kangss
Rank: 7Rank: 7Rank: 7
等 级:贵宾
威 望:14
帖 子:289
专家分:684
注 册:2014-6-12
收藏
得分:4 
可能跟“虚拟打印机”有关
虚拟打印机,也是打印机,真机打印机,打印任务可以重名,进度打印管理器队列中
虚拟打印机没用过,猜测:它的目的是让你另存为pdf的,既然是打印机,就不存在C盘、D盘,所以,你只能手动保存
2025-03-05 18:28
nbwww
Rank: 8Rank: 8
等 级:贵宾
威 望:11
帖 子:345
专家分:835
注 册:2021-1-9
收藏
得分:4 
LOCAL lcTableName, lcPDFFileName, lcReportName, lcPrinterName

* 设置报表文件名
lcReportName = "dy01tcz.frx"

* 设置虚拟打印机名称
lcPrinterName = "Microsoft Print to PDF"

* 获取当前目录下的所有符合要求的表文件
LOCAL ARRAY laTables[1]
ADIR(laTables, "dyzkz_*.dbf")

* 遍历每个表文件
FOR i = 1 TO ALEN(laTables, 1)
    lcTableName = laTables[i, 1]
   
    * 生成对应的 PDF 文件名
    lcPDFFileName = STRTRAN(lcTableName, ".dbf", ".pdf")
   
    * 设置数据环境
    USE (lcTableName) ALIAS tempTable
   
    * 设置默认打印机为 Microsoft Print to PDF
    SET PRINTER TO NAME (lcPrinterName)
   
    * 配置打印机输出路径(需要调用 Windows API 或外部工具)
    * 这里假设你已经通过其他方式配置了虚拟打印机的默认保存路径
   
    * 生成报表并输出为 PDF
   _CLIPTEXT=lcPDFFileName
KEYBOARD '{CTRL+V}'
KEYBOARD '{Enter}'
report form (lcReportName) to print NOCONSOLE
 *   REPORT FORM (lcReportName) TO FILE (lcPDFFileName) NOCONSOLE NOEJECT
   
    * 关闭表
    USE IN tempTable
ENDFOR


2025-03-05 18:57
sam_jiang
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:14
帖 子:865
专家分:1357
注 册:2021-10-13
收藏(1)
得分:0 
楼上的代码可行,就是读代码的时候感觉有点不可思议,怎么在调用打印程序先输入文件名和回车键?
类似的:
_CLIPTEXT="test.pdf"
KEYBOARD '{CTRL+V}'
KEYBOARD '{Enter}'
cfile=GETFILE("pdf")
?cfile
之前有人问如何在getfile()中输入文件名,以便保存文件,就是用这个方法;我后来建议他用putfile()

我让DS给我生成一段调用WinAPI的代码,没有验证,你们可以拿去试试:
程序代码:
* 声明 Windows API 函数
DECLARE INTEGER OpenPrinter IN winspool.drv STRING pPrinterName, INTEGER @phPrinter, INTEGER pDefault
DECLARE INTEGER StartDocPrinter IN winspool.drv INTEGER hPrinter, INTEGER Level, STRING @pDocInfo
DECLARE INTEGER StartPagePrinter IN winspool.drv INTEGER hPrinter
DECLARE INTEGER WritePrinter IN winspool.drv INTEGER hPrinter, STRING @pBuf, INTEGER cbBuf, INTEGER @pcWritten
DECLARE INTEGER EndPagePrinter IN winspool.drv INTEGER hPrinter
DECLARE INTEGER EndDocPrinter IN winspool.drv INTEGER hPrinter
DECLARE INTEGER ClosePrinter IN winspool.drv INTEGER hPrinter

* 定义常量
#DEFINE PRINTER_ACCESS_USE  8  && 打印机访问权限
#DEFINE DOC_INFO_1_SIZE  12     && DOC_INFO_1 结构体大小(按字节计算)

* 初始化变量
LOCAL lcPrinterName, hPrinter, lcDocInfo, lcData, lnResult, lnBytesWritten

* [color=#800000]1. 指定打印机名称(必须与系统中安装的名称一致)[/color]
lcPrinterName = "Microsoft Print to PDF" + CHR(0)  && 注意:名称需完全匹配

* [color=#800000]2. 打开打印机句柄[/color]
hPrinter = 0
lnResult = OpenPrinter(lcPrinterName, @hPrinter, PRINTER_ACCESS_USE)
IF lnResult = 0 OR hPrinter = 0
    MESSAGEBOX("无法打开打印机!错误代码:" + TRANSFORM(GetLastError()))
    RETURN
ENDIF

* [color=#800000]3. 准备 DOC_INFO_1 结构体(包含输出文件名)[/color]
* 结构体定义:https:[color=#808080]//docs./en-us/windows/win32/printdocs/doc-info-1[/color]
* 字段顺序:pDocName (LPTSTR), pOutputFile (LPTSTR), pDatatype (LPTSTR)
lcOutputFile = "C:\MyReport.pdf" + CHR(0)  && 输出路径(必须存在)
lcDocInfo = "My Document" + CHR(0) + ;  && 文档名称(任意)
           lcOutputFile + ;             && 输出文件名
           "RAW" + CHR(0)               && 数据类型(通常为 RAW 或 NT EMF)

* [color=#800000]4. 开始打印作业[/color]
lnJobID = StartDocPrinter(hPrinter, 1, lcDocInfo)
IF lnJobID <= 0
    MESSAGEBOX("StartDocPrinter 失败!错误代码:" + TRANSFORM(GetLastError()))
    ClosePrinter(hPrinter)
    RETURN
ENDIF

* [color=#800000]5. 开始页面[/color]
IF StartPagePrinter(hPrinter) = 0
    MESSAGEBOX("StartPagePrinter 失败!错误代码:" + TRANSFORM(GetLastError()))
    EndDocPrinter(hPrinter)
    ClosePrinter(hPrinter)
    RETURN
ENDIF

* [color=#800000]6. 写入打印数据(例如报表内容)[/color]
* 假设已生成报表内容到字符串 lcData
* 生成示例数据(实际应用中替换为报表内容)
lcData = "Hello, this is a test PDF content." + CHR(13) + CHR(10)

* 发送数据到打印机
lnBytesWritten = 0
lnResult = WritePrinter(hPrinter, lcData, LEN(lcData), @lnBytesWritten)
IF lnResult = 0
    MESSAGEBOX("WritePrinter 失败!错误代码:" + TRANSFORM(GetLastError()))
    EndPagePrinter(hPrinter)
    EndDocPrinter(hPrinter)
    ClosePrinter(hPrinter)
    RETURN
ENDIF

* [color=#800000]7. 结束页面和文档[/color]
EndPagePrinter(hPrinter)
EndDocPrinter(hPrinter)

* [color=#800000]8. 关闭打印机句柄[/color]
ClosePrinter(hPrinter)

MESSAGEBOX("PDF 文件已保存到:" + lcOutputFile)

2025-03-05 19:40
csyx
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:火星
等 级:版主
威 望:37
帖 子:735
专家分:2958
注 册:2018-3-13
收藏
得分:0 
以下是引用sam_jiang在2025-3-5 19:40:21的发言:
我让DS给我生成一段调用WinAPI的代码
牛头不对马嘴,ds 可谓是把一本正经的胡说八道发挥到了极致

这家伙很懒,啥也没留下
2025-03-07 06:28
sam_jiang
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:14
帖 子:865
专家分:1357
注 册:2021-10-13
收藏
得分:0 
回复 8楼 csyx
它还没有那么完美,但已经胜过其他很多的AI产品了。
2025-03-09 22:11
sych
Rank: 7Rank: 7Rank: 7
等 级:黑侠
威 望:7
帖 子:345
专家分:572
注 册:2019-10-11
收藏
得分:4 
安装Universal Document Converter,然后在代码中如下调用即可
objUDC = CREATEOBJECT("UDC.APIWrapper")
itfPrinter = objUDC.Printers("Universal Document Converter")
itfProfile = itfPrinter.Profile
itfProfile.PageSetup.ResolutionX = 300
itfProfile.PageSetup.ResolutionY = 300
itfProfile.FileFormat.ActualFormat = 2  &&FMT_JPG
itfProfile.FileFormat.PDF.ColorSpace = 24  &&CS_TRUECOLOR
itfProfile.FileFormat.PDF.Multipage = 2  &&MM_MULTI
itfProfile.OutputLocation.Mode = 1  &&LM_PREDEFINED
itfProfile.OutputLocation.FolderPath = "C:\Out"  &&路径
itfProfile.OutputLocation.FileName = "&[DocName(0)] -- &[Date(0)] -- &[Time(0)].&[ImageType]"  &&文件名
itfProfile.OutputLocation.OverwriteExistingFile = .F.
SET PRINTER TO NAME ("Universal Document Converter")
2025-03-10 07:04
快速回复:求助各位大神自动保存问题:测试发现还需要手动输入文件名进行保存,为 ...
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.032072 second(s), 8 queries.
Copyright©2004-2025, BC-CN.NET, All Rights Reserved